하나의 열에서 SELECT DISTINCT


258

SQL Server를 사용하면 ...

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

내가 원하는

1   FOO-23  Orange
3   FOO-24  Apple

이 검색어는 저를 찾지 못했습니다. 하나의 열에서 DISTINCT를 어떻게 선택합니까?

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

1
SKU 열 데이터의 접미사를 신경 쓰지 않는다고 가정 할 수 있습니까? IE, 당신은 "FOO-xx"가 아닌 "FOO-"에만 관심이 있습니다
— Kane

3
다른 값보다 ID = 1, SKU = FOO-23을 선택하는 논리는 무엇입니까? ID = 1에 대해 구체적으로 응답하지만 일반적인 경우에는 실패하는 쿼리를 쉽게 만들 수 있습니다.
— gbn

4
gbn-이것은 지나치게 단순화 된 예입니다 (분명히). 내가 보여 주려는 것은 두 기준을 모두 만족시키는 한 가지 예입니다. 논리를 선택하지 않아도됩니다.
— mmcglynn 2016 년

답변:


323

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

37
쿼리에 CTE 를 사용하지 않습니다 . 그것은 단지 파생 테이블입니다. 그러나 여기서 CTE를 사용할 수 있다고 생각합니다.
— Mark Byers

oracle에 대해 "있는 그대로"-> ... 어느 SKU가 'FOO %'와 같은지) a. RowNumber = 1
— Andre Nel

CTE (; WITH CTE ......)가 아니지만 작동합니다. 내부에서 파티션을 가진 하위 쿼리의 더 많은 것 ....
— user274294

이것은 다양한 중복 감사에 정말 유용한 경우입니다
— ASLIM

42

가장 간단한 해결책은 하위 쿼리를 사용하여 쿼리와 일치하는 최소 ID를 찾는 것입니다. 하위 쿼리에서는 다음 GROUP BY대신 사용 합니다 DISTINCT.

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

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


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

8
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
GROUP BY가 올바른 방법이라고 생각하기 때문에 +1하려고했지만 최소 ID와 최소 SKU가 동일한 레코드에 속하지 않을 수 있습니다. 특정 PRODUCT에 대해보고 할 올바른 ID 및 SKU가 무엇인지 판단하기가 어렵습니다.
— Carl Manaster

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  

0

다음은 기본적으로 다른 두 가지 답변과 동일한 버전이지만 일부 인라인 값으로 인해 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]
)

결과

ID  SKU     PRODUCT
1   FOO-23  Orange
3   FOO-24  Apple

나는 다음을 무시했다 ...

WHERE ([SKU] LIKE 'FOO-%')

저자의 유일한 부분은 잘못된 코드이며 질문의 일부는 아닙니다. 여기를 찾는 사람들에게는 도움이되지 않을 것입니다.


-1

이 시도:

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

당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.