2009-06-08 14 views
200

にDISTINCT SELECT、私は...私はSQL Serverを使用して1列

1 FOO-23 Orange 
3 FOO-24 Apple 

をしたい

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

このクエリは、そこに私を取得されていませんしています。 1つの列でDISTINCTをどのように選択できますか?

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

私たちは、あなたがSKU列データのサフィックスを気にしないことを前提とすることはできますか? I.E.あなたは「FOO-xx」でなく「FOO-xx」のみを気にします – Kane

+2

ID = 1、SKU = FOO-23を他の値よりも選択するあなたのロジックは何ですか? ID = 1では具体的に答えるクエリを作成するのは簡単ですが、一般的なケースでは失敗します – gbn

+2

gbn - これはあまり単純化された例です(明らかに)。私が提示しようとしているのは、両方の基準を満たす1つの例です。 1つが選択されるロジックはありません(そして、そうである必要はありません)。 – mmcglynn

答えて

259

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 
+30

クエリで[CTE](http://msdn.microsoft.com/en-us/library/ms190766.aspx)を使用していません。それは単なる派生テーブルです。しかし、ここにCTEを使用することができたのはあなたが正しいです。 –

+0

oracle - > ...のように "AS"を除外するWHERE SKU LIKE 'FOO%')a a.RowNumber = 1 –

12

はこの試してみてください。

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
OPは彼のsamle出力は(以前に、今すべてが示されている、唯一の1つの結果行を持っていた)修正したら、これが正しいクエリは次のとおりです。

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

GROUP BYは正しい方法だと思うので、これを+1しようとしましたが、最小IDと最小SKUが同じレコードに属していないことがあります。特定のPRODUCTについて報告する正しいIDとSKUが何であるかを判断するのは難しいです。 –

34

最も簡単な解決策は、あなたのクエリに一致する最小IDを見つけるためのサブクエリを使用することです。サブクエリでは、GROUP BY代わりのDISTINCTを使用します。

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

はこれを試してみてください:[TESTDATA] WHERE IdをIN(製品別[TESTDATA]グループからDISTINCT MIN(同上)SELECT)FROM

SELECT *

+0

は結果を返しません。動作しません – DoodleKana

5

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 
関連する問題