web-dev-qa-db-fra.com

SELECT DISTINCT sur une colonne

En utilisant SQL Server, j'ai ...

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

Je voudrais

1   FOO-23  Orange
3   FOO-24  Apple

Cette requête ne me mène pas là. Comment puis-je sélectionner DISTINCT sur une seule colonne?

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

En supposant que vous soyez sur SQL Server 2005 ou supérieur, vous pouvez utiliser un CTE avec 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
303
Aaron Alton

La solution la plus simple consiste à utiliser une sous-requête pour trouver l'ID minimum correspondant à votre requête. Dans la sous-requête, vous utilisez GROUP BY au lieu de DISTINCT:

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

essaye ça:

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
une fois que le PO a corrigé sa sortie de samle (auparavant, il n’avait qu’UNE ligne de résultat, elle est maintenant affichée), c’est la requête correcte:

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
13
KM.

Je sais que cela a été demandé il y a plus de 6 ans, mais la connaissance reste une connaissance. C'est une solution différente de toutes les solutions ci-dessus, car je devais l'exécuter sous 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  
8
Bartosz X
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'
6
Lecko

Voici une version, essentiellement la même que quelques autres réponses, mais que vous pouvez copier et coller dans votre serveur SQL Management Studio pour tester (et sans générer de tables inutiles), grâce à certaines valeurs en ligne.

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]
)

Résultat

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

J'ai ignoré ce qui suit ...

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

comme sa seule partie du code défectueux des auteurs et pas une partie de la question. Il est peu probable que cela soit utile aux personnes qui cherchent ici.

0
Ivan

Essaye ça:

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

0
Anna Karthi