MS-SQL - wie kann man in der where Bedingung nur den ersten Datensatz (TOP 1) ermitteln?
Hallo,
wir nutzen den MS-SQL Server 2012.
Für eine Abfrage über mehrere Tabellen brauche ich als Ergebnis der Unterabfrage nur den letzen Datensatz seine Anfrage pro Kunden zurück.
Dieser wird dann über die Kundennummer wieder mit zwei anderen Tabelle verknüpft.
Frage:
Gibt es die Möglichkeit in einer Abfrage in der where Bedingung als Ergebnis nur die letzte Anfrage eines Kunden in einen Anfragezeitraum zurückzuliefern, so wie am es sonst mit "select TOP 1 ... order by desc" für die ganze Tabelle hinbekommt.
In diesem Fall soll das Ergebnis aber nur die letzte Anfrage pro Kunden und nicht pro Tabelle zurückgegeben werden.
Meine Unterabfrage sieht so aus:
select kdnr from tblwebBuchungen
WHERE herkunft in ('www.domain1.de','www.domain2.de', 'www.domain3.de')
and (anfrageDatum >= '01.10.2016')
AND (anfrageDatum <= '31.10.2017')
Da ein Kunde mehrere Anfrage in den Anfragezeitraum gemacht haben kann, brauche ich jetzt in der where Bedingung zusätzlich so etwas wie "TOP 1 order by anfrageDatum desc" .
Als Ergebnis würde dann eine Liste mit allen Kunden und ihren LETZTEN Anfragen in den Zeitraum herauskommen.
Dies würde ich später wieder mit zwei weiteren Tabellen verknüpfen um der letzten Anfrage des jeweiligen Kunden mit seiner letzten Buchungen zu verknüpfen.
Die ganze Abfrage sieht so aus. Leider konnte es eben zu doppelten Buchungen bei Kunden die mehrere Anfragen gemacht haben, aber nur einmal gebucht haben.
Die Ursache liegt in der Tabelle tblwebBuchungen. Hier brauche ich nur die letzte Anfrage pro Kunde:
SELECT vorgang.kdnr, buchungen.idBuchnr, tblwebBuchungen.objektNr, buchungen.mietpr, tblwebBuchungen.herkunft,
FROM vorgang INNER JOIN
tblwebBuchungen ON vorgang.kdnr = tblwebBuchungen.kdnr INNER JOIN
buchungen ON vorgang.idBuchNr = buchungen.idBuchnr
WHERE (tblwebBuchungen.herkunft = 'www.domain1.de')
AND (vorgang.vgart = 'BU') AND (vorgang.von >= '01.01.2017')
AND (vorgang.bis <= '31.12.2017')
AND (tblwebBuchungen.anfrageDatum >= '01.10.2016')
AND (tblwebBuchungen.anfrageDatum <= '31.10.2017')
ORDER BY vorgang.kdnr DESC
Besten Dank,
Rene
wir nutzen den MS-SQL Server 2012.
Für eine Abfrage über mehrere Tabellen brauche ich als Ergebnis der Unterabfrage nur den letzen Datensatz seine Anfrage pro Kunden zurück.
Dieser wird dann über die Kundennummer wieder mit zwei anderen Tabelle verknüpft.
Frage:
Gibt es die Möglichkeit in einer Abfrage in der where Bedingung als Ergebnis nur die letzte Anfrage eines Kunden in einen Anfragezeitraum zurückzuliefern, so wie am es sonst mit "select TOP 1 ... order by desc" für die ganze Tabelle hinbekommt.
In diesem Fall soll das Ergebnis aber nur die letzte Anfrage pro Kunden und nicht pro Tabelle zurückgegeben werden.
Meine Unterabfrage sieht so aus:
select kdnr from tblwebBuchungen
WHERE herkunft in ('www.domain1.de','www.domain2.de', 'www.domain3.de')
and (anfrageDatum >= '01.10.2016')
AND (anfrageDatum <= '31.10.2017')
Da ein Kunde mehrere Anfrage in den Anfragezeitraum gemacht haben kann, brauche ich jetzt in der where Bedingung zusätzlich so etwas wie "TOP 1 order by anfrageDatum desc" .
Als Ergebnis würde dann eine Liste mit allen Kunden und ihren LETZTEN Anfragen in den Zeitraum herauskommen.
Dies würde ich später wieder mit zwei weiteren Tabellen verknüpfen um der letzten Anfrage des jeweiligen Kunden mit seiner letzten Buchungen zu verknüpfen.
Die ganze Abfrage sieht so aus. Leider konnte es eben zu doppelten Buchungen bei Kunden die mehrere Anfragen gemacht haben, aber nur einmal gebucht haben.
Die Ursache liegt in der Tabelle tblwebBuchungen. Hier brauche ich nur die letzte Anfrage pro Kunde:
SELECT vorgang.kdnr, buchungen.idBuchnr, tblwebBuchungen.objektNr, buchungen.mietpr, tblwebBuchungen.herkunft,
FROM vorgang INNER JOIN
tblwebBuchungen ON vorgang.kdnr = tblwebBuchungen.kdnr INNER JOIN
buchungen ON vorgang.idBuchNr = buchungen.idBuchnr
WHERE (tblwebBuchungen.herkunft = 'www.domain1.de')
AND (vorgang.vgart = 'BU') AND (vorgang.von >= '01.01.2017')
AND (vorgang.bis <= '31.12.2017')
AND (tblwebBuchungen.anfrageDatum >= '01.10.2016')
AND (tblwebBuchungen.anfrageDatum <= '31.10.2017')
ORDER BY vorgang.kdnr DESC
Besten Dank,
Rene
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 352349
Url: https://administrator.de/forum/ms-sql-wie-kann-man-in-der-where-bedingung-nur-den-ersten-datensatz-top-1-ermitteln-352349.html
Ausgedruckt am: 22.04.2025 um 06:04 Uhr
2 Kommentare
Neuester Kommentar
Ich würde das so machen:
ROW_NUMBER() in einem Subselect ist auf jedenfall ein richtiger Weg. Ob die Paritionierung und die Sortierung richtig sind müsstest du mal anhand deiner Daten prüfen.
SELECT t.kdnr, t.idBuchnr, t.objektNr, t.mietpr, t.herkunft
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY vorgang.kdnr ORDER BY buchungen.idBuchnr DESC) AS zeile,
vorgang.kdnr, buchungen.idBuchnr, tblwebBuchungen.objektNr, buchungen.mietpr, tblwebBuchungen.herkunft
FROM vorgang
INNER JOIN tblwebBuchungen
ON vorgang.kdnr = tblwebBuchungen.kdnr
INNER JOIN buchungen
ON vorgang.idBuchNr = buchungen.idBuchnr
WHERE tblwebBuchungen.herkunft = 'www.domain1.de'
AND vorgang.vgart = 'BU'
AND vorgang.von >= '01.01.2017'
AND vorgang.bis <= '31.12.2017'
AND tblwebBuchungen.anfrageDatum BETWEEN '01.10.2016' AND '31.10.2017'
) t
WHERE t.zeile = 1
ORDER BY t.kdnr DESC
Hallo Rene,
die von ukulele vorgeschlagene row_number ist zwar eine Möglichkeit, aber nicht die schnellste. Besser ist da sowas wie "cross apply":
Gruß, Mad Max
die von ukulele vorgeschlagene row_number ist zwar eine Möglichkeit, aber nicht die schnellste. Besser ist da sowas wie "cross apply":
SELECT vorgang.kdnr, buchungen.idBuchnr, tblwebBuchungen.objektNr, buchungen.mietpr, tblwebBuchungen.herkunft,
FROM vorgang
cross apply (
select top (1) *
from tblwebBuchungen
where kdnr = vorgang.kdnr
and herkunft = 'www.domain1.de'
and anfrageDatum between '01.10.2016' and '31.10.2017'
order by anfrageDatum desc
) as tblwebBuchungen
INNER JOIN buchungen ON vorgang.idBuchNr = buchungen.idBuchnr
WHERE (vorgang.vgart = 'BU')
AND (vorgang.von >= '01.01.2017')
AND (vorgang.bis <= '31.12.2017')
ORDER BY vorgang.kdnr DESC
Gruß, Mad Max