blueeyephoenix
Goto Top

SQL zweit höchstes Datum aus 3 Tabellen

Hallo Community,

ich habe da ein Problem und zwar will ich aus mit einer SQL Abfrage einem Objekt aus einer Datenbank ein Datum zuweisen von der vorletzten Bearbeitung. Diese Datum ist mit der Tabelle aber leider nicht direkt zu erreichen.

Tabelle1: Objekttabelle
Objektnummer Objektname
1 Haus
2 Garten
3 Hof

Tabelle2: Objektverwendung
Objektnummer, Objektbearbeitung
1 10
2 12
3 13

Tabelle3: Objektbearbeitung
Objektbearbeitung, Datum, Bereich
10 15.01.2020 1
10 25.02.2020 1
10 20.03.2020 2
10 20.04.2020 1

So sind die Tabellen grob aufgebaut. Davon hätte ich gern angezeigt:
Objektnummer Datum Bereich
10 25.02.2020 1

Folgendes habe ich versucht
select 
a.Objektnummer,
c.Bereich,
max(c.Datum) as Datum
from Objekttabelle a

left join
(select
Objektnummer,
Objektbearbeitung
from Objektverwendung) b
on a.Objektnummer = b.Objektnummer

left join
(select 
Objektbearbeitung,
Datum,
Bereich
from Objektbearbeitung)c
on b.Objektbearbeitung = c.Objektbearbeitung

where c.Bereich = 1 and a.Objektnummer = 1 
and c.Datum < (select max(Datum) from Objektbearbeitung) 
group by c.Bereich, a.Objektnummer

Angezeigt bekomme ich aber immer den 20.04.2020 statt dem 25.02.2020. Habe schon viele Foren durch aber bekomme irgendwie immer nur das erste Datum angezeigt und hoffe das es jemanden gibt der meinen Denkfehler sieht.

Hilfe wäre echt super

Vielen Dank

Content-ID: 665539

Url: https://administrator.de/contentid/665539

Ausgedruckt am: 20.11.2024 um 02:11 Uhr

em-pie
Lösung em-pie 08.04.2021 aktualisiert um 14:47:45 Uhr
Goto Top
Moin,

eine Variante wäre, wenn du dein Sub-Select des Left-Joins um eine Einschränkung ergänzt (die spalte cumulate soll dir nur zeigen, was da eigentlich passiert.:
...
left join
 (select 
  Objektbearbeitung,
  Datum,
  Bereich,
  cumulate = OVER(PARTITION by Objektbearbeitung ORDER BY Objektbearbeitung, Datum, Bereich ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
  from Objektbearbeitung
  where OVER(PARTITION by Objektbearbeitung ORDER BY Objektbearbeitung, Datum, Bereich ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) = 2) c
on b.Objektbearbeitung = c.Objektbearbeitung
...

Das Statement ist Funktionsfähig für einen MSSQL. hast du eine anderes DBMS, musst du danach selbst einmal schauen.

Gruß
em-pie
HansDampf06
HansDampf06 08.04.2021 aktualisiert um 15:40:29 Uhr
Goto Top
Dein "Fehler" in der Abfrage ist meiner Meinung nach:


where ...
and c.Datum < (select max(Datum) from Objektbearbeitung)


Einerseits fragst Du das maximale Datum über alle Zeilen der Tabelle ab, obschon Du gedanklich eigentlich eine differenzierte Betrachtung meinst: Objektnummer, Bereich, MAX(Datum).

Andererseits ist es besser, die Unterabfrage aus der WHERE-Klausel in eine JOIN-Klausel zu verschieben:

LEFT JOIN (SELECT Objektbearbeitung, Bereich, MAX(Datum) FROM Objektbearbeitung GROUP BY Objektbearbeitung, Bereich) AS D ON C.Objektbearbeitung = D.Objektbearbeitung AND C.Bereich = D.Bereich

und dann die Bedingung in der WHERE-Klausel entsprechend anzupassen:

AND C.Datum < D.Datum

Das ist auch beim Debugging der Abfrage hinsichtlich ihrer möglichen und tatsächlichen Ergebnisse sinnvoller.

Viel Erfolg
HansDampf06
mbehrens
mbehrens 08.04.2021 um 17:42:43 Uhr
Goto Top
Wie wäre folgender Ansatz:

SELECT FIRST 1 SKIP 1
  OBJEKTTABELLE.OBJEKTNUMMER,
  OBJEKTBEARBEITUNG.BEREICH,
  OBJEKTBEARBEITUNG.DATUM
FROM
  OBJEKTBEARBEITUNG
  LEFT JOIN OBJEKTVERWENDUNG ON OBJEKTBEARBEITUNG.OBJEKTBEARBEITUNG = OBJEKTVERWENDUNG.OBJEKTBEARBEITUNG
  LEFT JOIN OBJEKTTABELLE ON OBJEKTVERWENDUNG.OBJEKTNUMMER = OBJEKTTABELLE.OBJEKTNUMMER
ORDER BY
  OBJEKTBEARBEITUNG.DATUM;