2009-06-08 38 views
200

Sử dụng SQL Server, tôi có ...SELECT DISTINCT trên một cột

ID SKU PRODUCT 
======================= 
1 FOO-23 Orange 
2 BAR-23 Orange 
3 FOO-24 Apple 
4 FOO-25 Orange 

Tôi muốn

1 FOO-23 Orange 
3 FOO-24 Apple 

truy vấn này không nhận được tôi ở đó. Làm thế nào tôi có thể CHỌN DISTINCT chỉ trên một cột?

SELECT 
[ID],[SKU],[PRODUCT] 
FROM [TestData] 
WHERE ([PRODUCT] = 
(SELECT DISTINCT [PRODUCT] FROM [TestData] WHERE ([SKU] LIKE 'FOO-%')) 
ORDER BY [ID] 
+1

Giả sử bạn không quan tâm đến hậu tố trên dữ liệu cột SKU? I.E., Bạn chỉ quan tâm đến "FOO-" chứ không phải "FOO-xx" – Kane

+2

Logic của bạn để chọn ID = 1, SKU = FOO-23 so với các giá trị khác là gì? Thật dễ dàng để tạo truy vấn trả lời cho ID = 1 nhưng không thành công cho trường hợp chung là – gbn

+2

gbn - đây là một ví dụ quá đơn giản (rõ ràng). Những gì tôi đang cố gắng thể hiện là một ví dụ đáp ứng cả hai tiêu chí. Không có (và không cần) logic mà cái nào được chọn. – mmcglynn

Trả lời

259

Giả sử bạn đang sử dụng SQL Server 2005 trở lên, bạn có thể sử dụng CTE với ROW_NUMBER():

SELECT * 
FROM (SELECT ID, SKU, Product, 
       ROW_NUMBER() OVER (PARTITION BY PRODUCT ORDER BY ID) AS RowNumber 
     FROM MyTable 
     WHERE SKU LIKE 'FOO%') AS a 
WHERE a.RowNumber = 1 
+30

Bạn không sử dụng [CTE] (http://msdn.microsoft.com/en-us/library/ms190766.aspx) trong truy vấn của mình. Đó chỉ là một bảng có nguồn gốc. Nhưng bạn nói đúng rằng bạn * có thể * đã sử dụng một CTE ở đây. –

+0

bỏ "AS" cho oracle -> ... WHERE SKU LIKE 'FOO%') WHERE a.RowNumber = 1 –

12

thử điều này:

SELECT 
    t.* 
    FROM TestData t 
     INNER JOIN (SELECT 
         MIN(ID) as MinID 
         FROM TestData 
         WHERE SKU LIKE 'FOO-%' 
        ) dt ON t.ID=dt.MinID 

EDIT
khi OP điều chỉnh sản lượng samle mình (trước đây chỉ có một kết quả liên tiếp, hiện nay có tất cả được hiển thị), đây là truy vấn chính xác:

declare @TestData table (ID int, sku char(6), product varchar(15)) 
insert into @TestData values (1 , 'FOO-23'  ,'Orange') 
insert into @TestData values (2 , 'BAR-23'  ,'Orange') 
insert into @TestData values (3 , 'FOO-24'  ,'Apple') 
insert into @TestData values (4 , 'FOO-25'  ,'Orange') 

--basically the same as @Aaron Alton's answer: 
SELECT 
    dt.ID, dt.SKU, dt.Product 
    FROM (SELECT 
       ID, SKU, Product, ROW_NUMBER() OVER (PARTITION BY PRODUCT ORDER BY ID) AS RowID 
       FROM @TestData 
       WHERE SKU LIKE 'FOO-%' 
     ) AS dt 
    WHERE dt.RowID=1 
    ORDER BY dt.ID 
4
SELECT min (id) AS 'ID', min(sku) AS 'SKU', Product 
    FROM TestData 
    WHERE sku LIKE 'FOO%' -- If you want only the sku that matchs with FOO% 
    GROUP BY product 
    ORDER BY 'ID' 
+3

Sẽ +1 điều này, bởi vì tôi nghĩ GROUP BY là đúng cách để đi - nhưng ID tối thiểu và SKU tối thiểu có thể không xảy ra thuộc cùng một bản ghi. Thật khó để xác định ID và SKU chính xác là gì để báo cáo cho một PRODUCT nhất định. –

34

Giải pháp đơn giản nhất là nên sử dụng một subquery cho việc tìm kiếm ID tối thiểu phù hợp với truy vấn của bạn. Trong truy vấn con bạn sử dụng GROUP BY thay vì DISTINCT:

SELECT * FROM [TestData] WHERE [ID] IN (
    SELECT MIN([ID]) FROM [TestData] 
    WHERE [SKU] LIKE 'FOO-%' 
    GROUP BY [PRODUCT] 
) 
0

Hãy thử điều này:

SELECT * FROM [TestData] WHERE Id IN (SELECT MIN DISTINCT (Id) FROM [TestData] GROUP BY sản phẩm)

+0

không trả về kết quả. Không hoạt động – DoodleKana

5

Tôi biết nó đã được hỏi hơn 6 năm trước, nhưng kiến ​​thức vẫn là kiến ​​thức. Đây là giải pháp khác so với tất cả ở trên, vì tôi phải chạy nó trong SQL Server 2000:

DECLARE @TestData TABLE([ID] int, [SKU] char(6), [Product] varchar(15)) 
INSERT INTO @TestData values (1 ,'FOO-23', 'Orange') 
INSERT INTO @TestData values (2 ,'BAR-23', 'Orange') 
INSERT INTO @TestData values (3 ,'FOO-24', 'Apple') 
INSERT INTO @TestData values (4 ,'FOO-25', 'Orange') 

SELECT DISTINCT [ID] = (SELECT TOP 1 [ID] FROM @TestData Y WHERE Y.[Product] = X.[Product]) 
       ,[SKU]= (SELECT TOP 1 [SKU] FROM @TestData Y WHERE Y.[Product] = X.[Product]) 
       ,[PRODUCT] 
      FROM @TestData X 
Các vấn đề liên quan