하나의 열에서 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.