DISTINCT sur une colonne et retourne les lignes TOP

9

Comment recherchez-vous trois clients uniques avec le plus grand Purchase_Cost?

Je veux appliquer le DISTINCTseul sur Customer_Name, mais la requête ci-dessous applique le distinct sur les trois colonnes. Comment dois-je modifier la requête pour obtenir la sortie souhaitée?

SELECT DISTINCT TOP 3 customer_name, order_no, Purchase_Cost  
FROM PurchaseTable 
ORDER BY Purchase_Cost

entrez la description de l'image ici

Neal
la source

Réponses:

9

Remplacez votre dbname et schemaName dans la requête suivante.

;WITH CTE AS 
(
SELECT  
       [Order_No]
      ,[Customer_Name]
      ,[Purchase_Cost]
     , ROW_NUMBER() OVER(PARTITION BY [customer Name] ORDER BY [Purchase Cost] DESC) AS "RowNumber"
  FROM [dbname].[schemaName].[PurchaseTable]
  )

  SELECT TOP(3)
       [Order_No]
      ,[Customer_Name]
      ,[Purchase_Cost]
  FROM CTE WHERE RowNumber=1
  ORDER BY [Purchase_Cost] DESC

Je suis sûr qu'il existe d'autres façons de faire de même. Je vous suggère de lire ceci .

SqlWorldWide
la source
1

s'il vous plaît essayez:

SELECT DISTINCT TOP 3  order_no, customer_name,  Purchase_Cost
FROM
(   SELECT order_no, customer_name, Purchase_Cost, ROW_NUMBER() OVER(PARTITION BY customer_name ORDER BY Purchase_Cost DESC) Orders
    FROM PurchaseTable
) A
WHERE A.Orders = 1
ORDER BY Purchase_Cost DESC
Fatih
la source
0

Je pense que cela pourrait être plus efficace que les autres solutions, à condition d'avoir un index sur: (Customer_Name, Purchase_Cost DESC) INCLUDE (Order_No)

;
WITH PurchaseTable AS
(
    SELECT * 
      FROM (VALUES ((501),('Carson'),(3400)),
                   ((502),('Thomas'),(625)),
                   ((503),('Daisy'),(4856)),
                   ((504),('Mary'),(2397)),
                   ((505),('Carson'),(5000))
           ) AS T(Order_No,Customer_Name,Purchase_Cost)
),
DistinctCustomers AS
(
    SELECT DISTINCT
           Customer_Name
      FROM PurchaseTable
)
SELECT TOP(3) 
       MaxCustomerOrder.Order_No,
       dc.Customer_Name,
       MaxCustomerOrder.Purchase_Cost
  FROM DistinctCustomers dc
 CROSS APPLY (SELECT TOP(1) * 
                FROM PurchaseTable pt 
               WHERE pt.Customer_Name = dc.Customer_Name 
               ORDER BY pt.Purchase_Cost DESC
             )    AS MaxCustomerOrder
 ORDER BY MaxCustomerOrder.Purchase_Cost DESC
;

Ou sans la définition de table en ligne:

;
WITH DistinctCustomers AS
(
    SELECT DISTINCT
           Customer_Name
      FROM PurchaseTable
)
SELECT TOP(3) 
       MaxCustomerOrder.Order_No,
       dc.Customer_Name,
       MaxCustomerOrder.Purchase_Cost
  FROM DistinctCustomers dc
 CROSS APPLY (SELECT TOP(1) * 
                FROM PurchaseTable pt 
               WHERE pt.Customer_Name = dc.Customer_Name 
               ORDER BY pt.Purchase_Cost DESC
             )    AS MaxCustomerOrder
 ORDER BY MaxCustomerOrder.Purchase_Cost DESC
;
Jonathan Roberts
la source
La première requête ne semble pas valide.
dezso
J'ai essayé de le réparer. Je ne sais pas quelle est la différence entre la requête 1 et 2.
ypercubeᵀᴹ
La requête 2 a simplement supprimé les données de la table en ligne. Vous n'en avez pas besoin si vous avez réellement la table contenant les données. Si vous n'avez pas la table réelle, comme moi, vous en aurez besoin pour tester son fonctionnement.
Jonathan Roberts