sélectionner des commands de clients débutants

J'ai besoin d'aide pour créer une requête SQL qui renvoie les commands des clients qui n'ont commandé qu'une seule fois.

Les arrays et les champs pertinents sont les suivants:

Order Customer ------- ----------- orderId customerId orderDate customerId etc. 

Je suis à la search d'un set de résultats d'loggings de commands où il n'y a qu'une occurrence de l'identifiant client. Pour l'set de données suivant …

 [orderId] [customerId] [orderDate] [etc.] ---------- ------------ ------------ ------------ o1 c1 1/1/14 foo o2 c2 1/1/14 baz o3 c3 1/3/14 bar o4 c2 1/3/14 wibble 

Je voudrais que les résultats soient

 [orderId] [orderDate] [etc.] --------- ----------- ------ o1 1/1/14 foo o3 1/3/14 bar 

Les commands o2 et o4 sont omises car c2 a commandé deux fois.

Toute aide serait grandement appréciée.

Désolé, n'a pas mis ma tentative ratée. C'est ce que j'ai essayé …

 SELECT customerId, orderId, orderDate, Count(*) FROM Orders GROUP BY orderId, orderDate, customerID HAVING Count(*) = 1 ORDER BY orderId 

Il semble returnner tous les ordres.

Essayez ce qui suit (en supposant SQL Server 2005+):

 ;WITH CTE AS ( SELECT *, N = COUNT(*) OVER(PARTITION BY customerId) FROM Orders ) SELECT * FROM CTE WHERE N = 1 

Comme il est parfois préférable d'utiliser une approche piétonne plutôt que des CTE complexes, vous pouvez utiliser une table dérivée si vous le souhaitez (mais puisque vous utilisez la clause OVER , vous aurez toujours besoin de SQL Server 2005+):

 SELECT * FROM ( SELECT *, N = COUNT(*) OVER(PARTITION BY customerId) FROM Orders) T WHERE N = 1 

Alternativement (si par exemple vous êtes dans une version plus ancienne que 2005 de SQL-Server), vous pouvez utiliser la méthode GROUP BY / HAVING COUNT(*)=1 pour find des clients avec seulement 1 command, puis join la table Orders ( pas besoin de fonctions agrégées dans toutes les colonnes):

 SELECT o.* FROM Orders o JOIN ( SELECT customerId FROM Orders GROUP BY customerId HAVING COUNT(*) = 1 ) c ON c.customerId = o.customerId ; 

ou utilisez NOT EXISTS (pas de COUNT() nécessaire et cela fonctionne même dans MySQL):

 SELECT o.* FROM Orders o WHERE NOT EXISTS ( SELECT 1 FROM Orders c WHERE c.customerId = o.customerId AND c.orderId <> o.orderId ) ; 

Cela list tous les premiers clients dans votre table ORDERS .

 SELECT [customerID], MIN([orderId]) AS [orderId], MIN([orderDate]) AS [orderDate], MIN([etc.]) AS [etc.] FROM [Orders] GROUP BY [customerID] HAVING Count(*) = 1 ORDER BY [customerID] 

Afin de ramener toutes les colonnes supplémentaires, vous devez les envelopper dans un agrégat tel que MIN/MAX .

Il est arbitraire d'utiliser car il n'y aura qu'une seule ligne par groupe de toute façon. Cela suppose que toutes les colonnes de la table sont des types de données valides pour une telle agrégation (exemples de types de données qui ne sont pas BIT ou XML )