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
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
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
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 665539
Url: https://administrator.de/contentid/665539
Ausgedruckt am: 20.11.2024 um 02:11 Uhr
3 Kommentare
Neuester Kommentar
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.:
Das Statement ist Funktionsfähig für einen MSSQL. hast du eine anderes DBMS, musst du danach selbst einmal schauen.
Gruß
em-pie
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
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
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
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;