Disons que j'ai une table d'adresses de clients:
CName | AddressLine
-------------------------------
John Smith | 123 Nowheresville
Jane Doe | 456 Evergreen Terrace
John Smith | 999 Somewhereelse
Joe Bloggs | 1 Second Ave
Dans la table, un client tel que John Smith peut avoir plusieurs adresses .. J'ai besoin de la requête select pour que cette table ne renvoie que la première ligne trouvée où il y a des doublons dans 'CName'. Pour cette table, elle doit renvoyer toutes les lignes sauf la 3ème (ou la 1ère - toutes ces adresses sont acceptables, mais une seule peut être renvoyée). le serveur a déjà vu la valeur de la colonne auparavant?
Une réponse très simple si vous dites que vous ne vous souciez pas de l'adresse utilisée.
SELECT
CName, MIN(AddressLine)
FROM
MyTable
GROUP BY
CName
Si vous voulez le premier selon, par exemple, une colonne "insérée", c'est une requête différente
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
En SQL 2k5 +, vous pouvez faire quelque chose comme:
;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
Vous pouvez utiliser row_number()
pour obtenir le numéro de la ligne. Il utilise la commande over
- la clause partition by
spécifie quand redémarrer la numérotation et le order by
sélectionne les éléments sur lesquels le numéro de ligne doit être commandé. Même si vous avez ajouté un order by
à la fin de votre requête, le classement sera conservé dans la commande over
lors de la numérotation.
select *
from mytable
where row_number() over(partition by Name order by AddressLine) = 1
Vous pouvez utiliser la syntaxe row_numer() over(partition by ...)
comme suit:
select * from
(
select *
, ROW_NUMBER() OVER(PARTITION BY CName ORDER BY AddressLine) AS row
from myTable
) as a
where row = 1
Cela crée une colonne appelée row
, qui est un compteur qui s'incrémente chaque fois qu'il voit la même CName
, et indexe ces occurrences par AddressLine
. En imposant where row = 1
, on peut sélectionner la CName
dont AddressLine
vient en premier par ordre alphabétique. Si le order by
était desc
, il choisirait alors la CName
dont AddressLine
vient en dernier par ordre alphabétique.
Cela vous donnera une ligne de chaque ligne en double. Il vous donnera également les colonnes de type bit, et cela fonctionne au moins dans 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
Si vous voulez trouver tous les doublons à la place, changez simplement rn = 1 en rn> 1 ..__