web-dev-qa-db-fra.com

DISTINCT pour une seule colonne

Disons que j'ai la requête suivante.

SELECT ID, Email, ProductName, ProductModel FROM Products

Comment puis-je le modifier pour qu'il ne renvoie pas de courriels en double?

En d'autres termes, lorsque plusieurs lignes contiennent le même email, je souhaite que les résultats n'incluent qu'une seule de ces lignes (de préférence la dernière). Les doublons dans les autres colonnes doivent être autorisés.

Des clauses telles que DISTINCT et GROUP BY semblent fonctionner sur des lignes entières. Donc, je ne suis pas sûr de savoir comment aborder cela.

131
Jonathan Wood

Si vous utilisez SQL Server 2005 ou supérieur, utilisez ceci:

SELECT *
  FROM (
                SELECT  ID, 
                        Email, 
                        ProductName, 
                        ProductModel,
                        ROW_NUMBER() OVER(PARTITION BY Email ORDER BY ID DESC) rn
                    FROM Products
              ) a
WHERE rn = 1

EDIT: Exemple utilisant une clause where:

SELECT *
  FROM (
                SELECT  ID, 
                        Email, 
                        ProductName, 
                        ProductModel,
                        ROW_NUMBER() OVER(PARTITION BY Email ORDER BY ID DESC) rn
                    FROM Products
                   WHERE ProductModel = 2
                     AND ProductName LIKE 'CYBER%'

              ) a
WHERE rn = 1
154
Chandu

Cela suppose que SQL Server 2005+ et votre définition de "last" est la clé maximale pour un courrier électronique donné.

;WITH CTE AS
(
SELECT ID, 
       Email, 
       ProductName, 
       ProductModel, 
       ROW_NUMBER() OVER (PARTITION BY Email ORDER BY ID DESC) AS RowNumber 
FROM   Products
)
SELECT ID, 
       Email, 
       ProductName, 
       ProductModel
FROM CTE 
WHERE RowNumber = 1
10
Pero P.

Lorsque vous utilisez DISTINCT, considérez-le comme une ligne distincte, pas une colonne. Il renverra uniquement les lignes dont les colonnes ne correspondent pas exactement.

SELECT DISTINCT ID, Email, ProductName, ProductModel
FROM Products

----------------------
1 | [email protected] | ProductName1 | ProductModel1
2 | [email protected] | ProductName1 | ProductModel1

La requête renverrait les deux lignes car la colonne ID est différente. Je suppose que la colonne ID est une colonne IDENTITY qui s'incrémente; si vous voulez renvoyer la dernière, je vous recommande quelque chose comme ceci:

SELECT DISTINCT TOP 1 ID, Email, ProductName, ProductModel
FROM Products
ORDER BY ID DESC

Le TOP 1 renverra uniquement le premier enregistrement. En le classant par la variable ID décroissant, il renverra les résultats avec la dernière ligne en premier. Cela vous donnera le dernier enregistrement.

5
jon3laze

Vous pouvez plus que cela en utilisant la fonction GROUP BY

SELECT ID, Email, ProductName, ProductModel FROM Products GROUP BY Email

5
Marshall Unduemi

Pour Access, vous pouvez utiliser la requête SQL Select que je présente ici:

Par exemple, vous avez cette table:

CLIENTE || NOMBRES || COURRIER

888 || T800 ARNOLD || [email protected]

123 || JOHN CONNOR || [email protected]

125 || SARAH CONNOR ||[email protected]

Et vous devez sélectionner uniquement des mails distincts . Vous pouvez le faire avec ceci:

SQL SELECT:

SELECT MAX(p.CLIENTE) AS ID_CLIENTE
, (SELECT TOP 1 x.NOMBRES 
    FROM Rep_Pre_Ene_MUESTRA AS x 
    WHERE x.MAIL=p.MAIL 
     AND x.CLIENTE=(SELECT MAX(l.CLIENTE) FROM Rep_Pre_Ene_MUESTRA AS l WHERE x.MAIL=l.MAIL)) AS NOMBRE, 
p.MAIL
FROM Rep_Pre_Ene_MUESTRA AS p
GROUP BY p.MAIL;

Vous pouvez l'utiliser pour sélectionner l'ID maximum, le nom du correspondant correspondant à cet ID maximum, vous pouvez ajouter n'importe quel autre attribut de cette manière. Puis à la fin, vous mettez la colonne distincte au filtre et vous ne la regroupez qu'avec la dernière colonne distincte.

Cela vous apportera l'ID maximum avec les données correspondantes, vous pouvez utiliser min ou toute autre fonction et vous répliquez cette fonction dans les sous-requêtes.

Cette sélection retournera:

CLIENTE || NOMBRES || COURRIER

888 || T800 ARNOLD || [email protected]

125 || SARAH CONNOR ||[email protected]

N'oubliez pas d'indexer les colonnes que vous sélectionnez et la colonne distincte ne doit pas contenir de données numériques en majuscules ou en minuscules, sinon cela ne fonctionnera pas… .. Cela fonctionnera également avec un seul courrier recommandé… ... Bonne codage !!!

0
jRam90

Essaye ça

;With Tab AS (SELECT DISTINCT Email FROM  Products)
SELECT Email,ROW_NUMBER() OVER(ORDER BY Email ASC) AS  Id FROM Tab
ORDER BY Email ASC
0
Abdullah Yousuf