SQL Abfrage mit Datum

Hallo,

Ich habe wieder mal eine Frage an die Profis unter euch :slight_smile:

Hier meine 3 Tabellen:

table1: stable
s_id | s_title
1 | stable1
2 | stable2

table2: animal
a_id | a_name
1 | Linda
2 | Berta
3 | Siggi

table3: removals
re_id | re_date | re_a_id | re_s_id
1 | 2017-01-10 | 1 | 1
2 | 2017-01-11 | 1 | 2
3 | 2017-01-11 | 2 | 1
4 | 2017-01-12 | 1 | 1
5 | 2017-01-13 | 1 | 2
6 | 2017-01-14 | 3 | 1

Erklärung Tabelle3:
Linda zieht am 10.1. in Stall 1
Linda zieht am 11.1. in Stall 2
Berta zieht am 11.1. in Stall 1
Linda zieht am 12.1. in Stall 1

Linda zieht am 13.1. in Stall 2
Siggi zieht am 14.1. in Stall 1

Nun möchte ich wissen, wie viele Tiere am 2017-01-12 im Stall1 waren:



select count(animal.a_id) from Animal as animal  where animal.a_id IN (select removal.re_a_id from Removal as removal where re_s_id = 1)

Ich bekomme nachtürlich 3 zurück, weil ich nicht weiß, wie ich es mit dem Datum lösen kann.
Als Antwort hätte ich gerne 2 (die 2 Fett-gedruckten)

Ich hoffe ich könnt mir helfen :slight_smile:

lg, JayJay

test=*# select re_a_id, re_s_id, max(re_date) from removals where re_date <= '2017-01-12' and re_s_id = 1 group by re_a_id, re_s_id ;
 re_a_id | re_s_id |    max     
---------+---------+------------
       1 |       1 | 2017-01-12
       2 |       1 | 2017-01-11
(2 Zeilen)

Das joinen der anderen Tabellen überlasse ich Dir zur Übung :wink:


die reine Anzahl:

test=*# select count(1) from (select re_a_id, re_s_id, max(re_date) from removals where re_date <= '2017-01-12' and re_s_id = 1 group by re_a_id, re_s_id ) foo;
 count 
-------
     2
(1 Zeile)

Hallo,

Danke für die schnelle Antwort. Aber:

Wenn Tier 3 am 1.1.2017 in Stall 1 einzieht und am 8.1.2017 in Stall 2 umzieht, ist es trotzdem bei deiner Abfrage für 12.1.2017 trotzdem dabei

ok.

test=*# select * from removals ;
 re_id |  re_date   | re_a_id | re_s_id 
-------+------------+---------+---------
     1 | 2017-01-10 |       1 |       1
     2 | 2017-01-11 |       1 |       2
     3 | 2017-01-11 |       2 |       1
     4 | 2017-01-12 |       1 |       1
     5 | 2017-01-13 |       1 |       2
     6 | 2017-01-14 |       3 |       1
     7 | 2017-01-01 |       3 |       1
     8 | 2017-01-08 |       3 |       2
(8 Zeilen)

test=*# select re_date, re_a_id, re_s_id from (select *, row_number() over (partition by re_a_id order by re_date desc) as current_place from removals where re_date <= '2017-01-12' order by re_a_id, re_date) foo where current_place = 1 and re_s_id = 1;
  re_date   | re_a_id | re_s_id 
------------+---------+---------
 2017-01-12 |       1 |       1
 2017-01-11 |       2 |       1
(2 Zeilen)

geht bestimmt noch eleganter …

Danke für deine Hilfe, ich verwende es mal so :sunglasses:

Hallo,

Nun bin ich wieder zurück mit einem weiteren Problem bei der Abfrage.

Wenn ein Tier nicht in Stall 1 sondern in Stall 8 beginnt, funktioniert es nicht mehr (wegen row_number)

Tabellenbeispiel:

re_id | re_date | re_a_id | re_s_id
-------±-----------±--------±--------
1 | 2017-01-10 | 1 | 7
2 | 2017-01-11 | 1 | 6
3 | 2017-01-11 | 2 | 8
4 | 2017-01-12 | 1 | 9
5 | 2017-01-13 | 1 | 6
6 | 2017-01-14 | 3 | 3
7 | 2017-01-01 | 3 | 1
8 | 2017-01-08 | 3 | 2


Kann man statt dem row_number direkt den Spaltenwert “re_s_id” verwenden? Alleine habe ich es nicht geschafft :frowning:

gelöst. Statt row_number() einfach last_value(re_s_id) angeben.

Hier, alt:

select re_date, re_a_id, re_s_id from (select *, row_number() over (partition by re_a_id order by re_date desc) as current_place from removals where re_date <= '2017-01-12' order by re_a_id, re_date) foo where current_place = 1 and re_s_id = 1;

und neu (so funktioniert’s):

select re_date, re_a_id, re_s_id from (select *, last_value(re_s_id) over (partition by re_a_id order by re_date desc) as current_place from removals where re_date <= '2017-01-12' order by re_a_id, re_date) foo where current_place = 1 and re_s_id = 1;