DISTINCT trên một cột và trả về các hàng TOP


9

Làm thế nào để bạn truy vấn cho ba khách hàng duy nhất với lớn nhất Purchase_Cost?

Tôi muốn áp dụng DISTINCTduy nhất trên Customer_Name, nhưng truy vấn bên dưới áp dụng phân biệt trên cả ba cột. Tôi nên sửa đổi truy vấn như thế nào để có được đầu ra mong muốn?

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

nhập mô tả hình ảnh ở đây

Câu trả lời:


9

Thay thế dbname và giản lược của bạn trong truy vấn sau đây.

;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

Tôi chắc chắn có những cách khác để làm như vậy. Tôi đề nghị bạn đọc .


1

Vui lòng thử:

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

0

Tôi nghĩ rằng các giải pháp khác có thể hiệu quả hơn, miễn là bạn có một chỉ mục trên: (Customer_Name, Purch_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
;

Hoặc không có định nghĩa bảng nội tuyến:

;
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
;

Truy vấn đầu tiên có vẻ không hợp lệ.
dezso

Tôi đã cố gắng sửa nó. Không chắc chắn sự khác biệt giữa truy vấn 1 và 2.
ypercubeᵀᴹ

Truy vấn 2 chỉ cần loại bỏ dữ liệu bảng nội tuyến. Bạn không cần nó nếu bạn thực sự có bảng với dữ liệu trong đó. Nếu bạn không có bảng thực tế, như tôi, bạn sẽ cần nó để kiểm tra xem nó có chạy không.
Jonathan Roberts
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.