21

このテーブルがあるとします [Table1]

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

次のようなレコードを取得するための SQL ステートメントは次のようになります: (group by [mark])。1 列目と 2 列目は完了しましたが、3 列目を達成する方法がわかりません ([名前] を同じ [マーク] で連結)

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

Microsoft SQL を使用しています。助けてください。ありがとう

4

4 に答える 4

35

MS SQL 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
于 2011-07-05T08:04:43.763 に答える
4

パフォーマンス関連の回答は次のとおりです。

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

大規模なクエリで XML 関数を使用すると、パフォーマンスが低下します。

CTE の使用は、パフォーマンスのスーパースターです。

リンクをチェックしてください、それは方法を説明します。

それを達成するための仕事はもっと多いことを認めます。

しかし、結果は数百万行のミリ秒です。

于 2011-07-06T17:43:00.007 に答える
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
于 2011-07-05T08:11:28.527 に答える