在一列上选择DISTINCT

mmc*_*ynn 248 sql t-sql sql-server distinct

使用SQL Server,我有......

ID  SKU     PRODUCT
=======================
1   FOO-23  Orange
2   BAR-23  Orange
3   FOO-24  Apple
4   FOO-25  Orange
Run Code Online (Sandbox Code Playgroud)

我想要

1   FOO-23  Orange
3   FOO-24  Apple
Run Code Online (Sandbox Code Playgroud)

这个问题不是让我在那里.如何在一列上选择DISTINCT?

SELECT 
[ID],[SKU],[PRODUCT]
FROM [TestData] 
WHERE ([PRODUCT] = 
(SELECT DISTINCT [PRODUCT] FROM [TestData] WHERE ([SKU] LIKE 'FOO-%')) 
ORDER BY [ID]
Run Code Online (Sandbox Code Playgroud)

Aar*_*ton 310

假设您使用的是SQL Server 2005或更高版本,则可以使用带有ROW_NUMBER()的CTE:

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
Run Code Online (Sandbox Code Playgroud)

  • 您没有在查询中使用[CTE](http://msdn.microsoft.com/en-us/library/ms190766.aspx).那只是一个派生表.但你是对的,你可以*在这里使用过CTE. (36认同)

Jak*_*ger 41

最简单的解决方案是使用子查询来查找与查询匹配的最小ID.在子查询中,您使用GROUP BY而不是DISTINCT:

SELECT * FROM [TestData] WHERE [ID] IN (
   SELECT MIN([ID]) FROM [TestData]
   WHERE [SKU] LIKE 'FOO-%'
   GROUP BY [PRODUCT]
)
Run Code Online (Sandbox Code Playgroud)


KM.*_*KM. 13

试试这个:

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

编辑
一旦OP纠正了他的samle输出(之前只有一个结果行,现在已全部显示),这是正确的查询:

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
Run Code Online (Sandbox Code Playgroud)


Iva*_*van 13

这是一个版本,基本上与其他几个答案相同,但是您可以将其复制粘贴到 SQL Server Management Studio 中进行测试(并且不会生成任何不需要的表),这要归功于一些内联值。

WITH [TestData]([ID],[SKU],[PRODUCT]) AS
(
    SELECT *
    FROM (
        VALUES
        (1,   'FOO-23',  'Orange'),
        (2,   'BAR-23',  'Orange'),
        (3,   'FOO-24',  'Apple'),
        (4,   'FOO-25',  'Orange')
    )
    AS [TestData]([ID],[SKU],[PRODUCT])
)

SELECT * FROM [TestData] WHERE [ID] IN 
(
    SELECT MIN([ID]) 
    FROM [TestData] 
    GROUP BY [PRODUCT]
)
Run Code Online (Sandbox Code Playgroud)

结果

ID  SKU     PRODUCT
1   FOO-23  Orange
3   FOO-24  Apple
Run Code Online (Sandbox Code Playgroud)

我忽略了以下...

WHERE ([SKU] LIKE 'FOO-%')
Run Code Online (Sandbox Code Playgroud)

因为它是作者错误代码的唯一部分,而不是问题的一部分。对于在这里寻找的人来说不太可能有帮助。


Bar*_*z X 8

我知道它是在6年前被问到的,但知识仍然是知识.这是与上述所有不同的解决方案,因为我必须在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  
Run Code Online (Sandbox Code Playgroud)


小智 7

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'
Run Code Online (Sandbox Code Playgroud)

  • 打算给+1这个,因为我认为GROUP BY是正确的方法 - 但最小ID和最小SKU可能不属于同一记录.很难确定报告给定PRODUCT的正确ID和SKU是什么. (3认同)

小智 6

尝试这个:

SELECT * FROM [TestData] WHERE Id IN(SELECT DISTINCT MIN(Id) FROM [TestData] GROUP BY Product)