एक कॉलम पर DISTINCT का चयन करें


258

SQL सर्वर का उपयोग करना, मेरे पास ...

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-" की परवाह करते हैं और "FOO-xx" की नहीं
केन

3
अन्य मूल्यों पर ID = 1, SKU = FOO-23 चुनने के लिए आपका तर्क क्या है? आईडी = 1 के लिए विशेष रूप से उत्तर देने वाली क्वेरी बनाना आसान है लेकिन एक सामान्य मामले के लिए विफल रहता है
gbn

4
gbn - यह एक अत्यधिक सरलीकृत उदाहरण (स्पष्ट रूप से) है। मैं जो दिखाने की कोशिश कर रहा हूं वह एक ऐसा उदाहरण है जो दोनों मानदंडों को पूरा करता है। ऐसा तर्क (और नहीं होना चाहिए) जिसमें से किसी एक को चुना गया हो।
mmcglynn

जवाबों:


323

यह मानते हुए कि आप SQL सर्वर 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 का उपयोग नहीं कर रहे हैं । वह सिर्फ एक व्युत्पन्न तालिका है। लेकिन आप सही हैं कि आप यहां सीटीई का उपयोग कर सकते हैं।
मार्क बायर्स

बाहर निकलें "AS" के लिए oracle -> ... जहां SKU LIKE 'FOO%') WHERE.R.RNNumber = 1
आंद्रे नेल

यह काम करता है, हालांकि यह सीटीई नहीं है (; सीटीई के साथ ......)। अंदर से विभाजन के साथ एक उप क्वेरी के अधिक ....
user274294

यह वास्तव में किसी भी दोहराव में उपयोगी मामला है धन्यवाद
ASLIM

42

सबसे सरल उपाय यह होगा कि आप अपनी क्वेरी से मेल खाते हुए न्यूनतम आईडी को खोजने के लिए एक सबक्वेरी का उपयोग करें। इसके 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

संपादित करें
ओ पी ने एक बार अपने 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
यह +1 करने जा रहा था, क्योंकि मुझे लगता है कि ग्रुप BY जाने का सही तरीका है - लेकिन न्यूनतम आईडी और न्यूनतम SKU एक ही रिकॉर्ड से संबंधित नहीं हो सकता है। यह निर्धारित करना कठिन है कि किसी दिए गए उत्पाद के लिए रिपोर्ट करने के लिए सही आईडी और SKU क्या हैं।
कार्ल मैनस्टर

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 सर्वर प्रबंधन स्टूडियो में पेस्ट कॉपी कर सकते हैं परीक्षण के लिए (और बिना किसी अवांछित तालिका उत्पन्न किए), कुछ इनलाइन मूल्यों के लिए धन्यवाद।

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-%')

लेखकों के अपने एकमात्र भाग के रूप में दोषपूर्ण कोड और प्रश्न का हिस्सा नहीं है। यहां लोगों को मददगार होने की संभावना नहीं है।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.