2011-07-05 11 views
20

मान लीजिए मैं इस तालिका [Table1] हैप्रत्येक समूह के लिए एक निश्चित स्तंभ से सभी स्ट्रिंग्स को श्रेणीबद्ध कैसे

Name Mark 
------- ------ 
ABC  10 
DEF  10 
GHI  10 
JKL  20 
MNO  20 
PQR  30 

क्या एक रिकार्ड है कि इस तरह दिखता है पुनः प्राप्त करने के लिए अपने SQL विवरण होना चाहिए: (समूह द्वारा [ निशान])। मैं

mark count  names 
---- -----  ----------- 
10  3  ABC,DEF,GHI 
20  2  JKL,MNO 
30  1  PQR 

मैं Microsoft SQL का उपयोग कर रहा (के साथ एक ही [निशान] concat [नाम]) 1 और 2 कॉलम किया है लेकिन कैसे तीसरे स्तंभ पूरा करने के लिए पता नहीं है। कृपया मदद करें। धन्यवाद

+0

आप किस डीबीएमएस का उपयोग कर रहे हैं? –

+0

माइक्रोसॉफ्ट एसक्यूएल। इस जानकारी को शामिल करने के लिए खेद है – yonan2236

+0

यह भी देखें http://stackoverflow.com/questions/451415/simulating-group-concat-mysql-function-in-ms-sql-server-2005 –

उत्तर

35

यदि एमएस एसक्यूएल 2005 या उच्चतर है।

declare @t table([name] varchar(max), mark int) 

insert @t values ('ABC', 10), ('DEF', 10), ('GHI', 10), 
    ('JKL', 20), ('MNO', 20), ('PQR', 30) 


select t.mark, COUNT(*) [count] 
    ,STUFF((
     select ',' + [name] 
     from @t t1 
     where t1.mark = t.mark 
     for xml path(''), type 
    ).value('.', 'varchar(max)'), 1, 1, '') [values] 
from @t t 
group by t.mark 

आउटपुट:

mark  count  values 
----------- ----------- -------------- 
10   3   ABC,DEF,GHI 
20   2   JKL,MNO 
30   1   PQR 
+1

+1 xml पथ ('') – Pankaj

+0

के लिए +1 [मूल्य] लिखते समय अंतर नहीं करता है? – Pankaj

+0

@ एसक्यूएल, यह केवल उपनाम है, इसलिए कोई फर्क नहीं पड़ता –

1

polishchuks समाधान अधिक सुरुचिपूर्ण है, लेकिन इस मूल रूप से एक ही बात है, हम बस अनुगामी अल्पविराम अलग ढंग से निपटने के लिए है।

CREATE TABLE #Marks(Name nchar(3), Mark int) 

INSERT INTO #Marks 

SELECT 'ABC', 10 UNION ALL 
SELECT 'DEF', 10 UNION ALL 
SELECT 'GHI', 10 UNION ALL 
SELECT 'JKL', 20 UNION ALL 
SELECT 'MNO', 20 UNION ALL 
SELECT 'PQR', 30 


SELECT 
    mark, 
    [count], 
    CASE WHEN Len(Names) > 0 THEN LEFT(Names, LEN(Names) -1) ELSE '' END names 
    FROM 
(
SELECT 
    Mark, 
    COUNT(Mark) AS [count], 
     (
     SELECT DISTINCT 
      Name + ', ' 
     FROM 
      #Marks M1 
     WHERE M1.Mark = M2.Mark 
     FOR XML PATH('')  
     ) Names 
FROM #Marks M2 
GROUP BY Mark 
) M 
+0

मुझे यकीन नहीं है कि अगर आप मार्क द्वारा समूह कर रहे हैं तो पहले सबक्वायरी में आपको पहले विशिष्ट खंड की आवश्यकता है, अगर मैं गलत हूं तो कृपया मुझे सही करें ... – Ram

+0

हाँ आपको इसकी आवश्यकता नहीं होगी – woggles

4

यहां एक प्रदर्शन-संबंधित उत्तर है!

http://jerrytech.blogspot.com/2010/04/tsql-concatenate-strings-1-2-3-and.html

एक बड़ी क्वेरी में XML कार्यों का उपयोग करते हुए एक प्रदर्शन हत्यारा है।

एक सीटीई का उपयोग एक प्रदर्शन सुपरस्टार है।

लिंक देखें, यह समझाएगा कि कैसे।

मैं इसे पूरा करने के लिए काम स्वीकार करता हूं।

लेकिन परिणाम लाखों पंक्तियों से मिलीसेकंड है।

0

उज्ज्वल बेन-गण पर आधारित, माइक्रोसॉफ्ट एसक्यूएल सर्वर 2005 के अंदर: टी-एसक्यूएल प्रोग्रामिंग, पी। 215:

IF OBJECT_ID('dbo.Table1') IS NOT NULL 
    DROP TABLE dbo.Table1 ; 
GO 
CREATE TABLE dbo.Table1 (Name VARCHAR(10), Mark INT) ; 

INSERT INTO dbo.Table1 (Name, Mark) VALUES ('ABC',  10) ; 
INSERT INTO dbo.Table1 (Name, Mark) VALUES ('DEF',  10) ; 
INSERT INTO dbo.Table1 (Name, Mark) VALUES ('GHI',  10) ; 
INSERT INTO dbo.Table1 (Name, Mark) VALUES ('JKL',  20) ; 
INSERT INTO dbo.Table1 (Name, Mark) VALUES ('MNO',  20) ; 
INSERT INTO dbo.Table1 (Name, Mark) VALUES ('PQR',  30) ; 


WITH DelimitedNames AS 
(
    SELECT Mark, T2.Count, 
     ( SELECT Name + ',' AS [text()] 
      FROM dbo.Table1 AS T1 
      WHERE T1.Mark = T2.Mark 
      ORDER BY T1.Mark 
      FOR XML PATH('')) AS Names 
    FROM (SELECT Mark, COUNT(*) AS Count FROM dbo.Table1 GROUP BY Mark) AS T2 
) 
SELECT Mark, Count, LEFT(Names, LEN(NAMES) - 1) AS Names 
FROM DelimitedNames ; 
संबंधित मुद्दे