Nehmen wir an, ich habe eine Tabelle mit Kundenadressen:
CName | AddressLine
-------------------------------
John Smith | 123 Nowheresville
Jane Doe | 456 Evergreen Terrace
John Smith | 999 Somewhereelse
Joe Bloggs | 1 Second Ave
In der Tabelle kann ein Kunde wie John Smith mehrere Adressen haben. Ich brauche die Auswahlabfrage für diese Tabelle, um nur die erste Zeile zurückzugeben, in der Duplikate in 'CName' gefunden wurden. Für diese Tabelle sollten alle Zeilen mit Ausnahme der 3. (oder 1.) zurückgegeben werden (jede dieser beiden Adressen ist in Ordnung, aber es kann nur eine zurückgegeben werden.) Gibt es ein Schlüsselwort, das ich der SELECT-Abfrage hinzufügen kann, um basierend darauf zu filtern, ob Server hat den Spaltenwert schon gesehen?
Eine sehr einfache Antwort, wenn Sie sagen, es ist Ihnen egal, welche Adresse verwendet wird.
SELECT
CName, MIN(AddressLine)
FROM
MyTable
GROUP BY
CName
Wenn Sie die erste entsprechend einer "eingefügten" Spalte haben möchten, ist es eine andere Abfrage
SELECT
M.CName, M.AddressLine,
FROM
(
SELECT
CName, MIN(Inserted) AS First
FROM
MyTable
GROUP BY
CName
) foo
JOIN
MyTable M ON foo.CName = M.CName AND foo.First = M.Inserted
In SQL 2k5 + können Sie Folgendes tun:
;with cte as (
select CName, AddressLine,
rank() over (partition by CName order by AddressLine) as [r]
from MyTable
)
select CName, AddressLine
from cte
where [r] = 1
Sie können row_number()
verwenden, um die Zeilennummer der Zeile abzurufen. Es verwendet den Befehl over
- die partition by
-Klausel gibt an, wann die Nummerierung erneut gestartet werden soll, und der order by
legt fest, worauf die Zeilennummer angeordnet werden soll. Selbst wenn Sie am Ende Ihrer Abfrage einen order by
hinzugefügt haben, bleibt die Reihenfolge im Befehl over
bei der Nummerierung erhalten.
select *
from mytable
where row_number() over(partition by Name order by AddressLine) = 1
Sie können die row_numer() over(partition by ...)
-Syntax wie folgt verwenden:
select * from
(
select *
, ROW_NUMBER() OVER(PARTITION BY CName ORDER BY AddressLine) AS row
from myTable
) as a
where row = 1
Dies bewirkt, dass eine Spalte mit dem Namen row
erstellt wird. Dies ist ein Zähler, der jedes Mal inkrementiert wird, wenn dieselbe Variable CName
angezeigt wird, und diese Vorkommen mit AddressLine
indiziert. Durch Auferlegen von where row = 1
kann man die CName
auswählen, deren AddressLine
alphabetisch zuerst kommt. Wenn der order by
desc
wäre, würde er die CName
auswählen, deren AddressLine
als letztes alphabetisch kommt.
Dadurch erhalten Sie eine Zeile jeder doppelten Zeile. Es gibt auch die Bit-Typ-Spalten, und es funktioniert zumindest in MS SQL Server.
(select cname, address
from (
select cname,address, rn=row_number() over (partition by cname order by cname)
from customeraddresses
) x
where rn = 1) order by cname
Wenn Sie stattdessen alle Duplikate suchen möchten, ändern Sie einfach rn = 1 in rn> 1 . Hoffe, das hilft