2

SQL Server 2012 の GROUP_CONCAT() MySQL 関数に相当するものを探しています。以下で説明するように、サブクエリを使用しません。

CREATE TABLE Temp
( 
ID INT PRIMARY KEY NOT NULL IDENTITY(1,1),
ColA varchar(900) NULL,
ColB varchar(900) NULL
)

INSERT INTO Temp (ColA, ColB)
SELECT 'A', 'some' UNION ALL
SELECT 'A', 'thing' UNION ALL
SELECT 'A', 'and' UNION ALL
SELECT 'B', 'some' UNION ALL
SELECT 'B', 'more' UNION ALL
SELECT 'B', 'and' UNION ALL
SELECT 'B', 'more' UNION ALL
SELECT 'C', 'things' UNION ALL
SELECT 'C', 'things'

-- Desired Output. Note that the lists are in descending order of frequency ('more' appears twice)
ColA, Frequency, ColBs
'B', 4, 'more, some, and'
'A', 3, 'some, thing, and'
'C', 2, 'things'

SELECT 
    ColA, 
    COUNT(*) as Frequency, 
    GROUP_CONCAT(ColB) --Would be nice
FROM Temp
GROUP BY ColA
ORDER BY Frequency DESC

これに対する SQL Server での一般的な答えは、サブクエリで STUFF() を使用することです。私の場合、パフォーマンスはまったく受け入れられません (2 億レコード、サブクエリあたり 26 秒 * 2 億 = 164 年)。

SELECT 
    ColA, 
    COUNT(*) as Frequency, 
    ISNULL(
        STUFF((
            SELECT ', ' + ColBs FROM
                (SELECT ColBs, Count(*) as Frequency
                FROM Temp sub
                WHERE sub.ColA = t.ColA
                GROUP BY ColB
                ORDER BY Frequency DESC)
            FOR XML PATH('')
        ), 1, 2, '')
    ), '') as ColBs --Would take 164 years on the entire data set
FROM Temp t
GROUP BY ColA
ORDER BY Frequency DESC

目的の出力は、上記のように、グループ化され、発生の降順に並べられた、一意の ColA ごとの ColB 値です。ただし、これは、テーブルを介して SINGLE QUERY で行う必要があります。

これを自分で構築し、「GROUP BY」呼び出しを放棄する必要がありますか? データ セットを手動で反復処理し、コンソール アプリケーションで新しいテーブルを作成しますか? または、私が見逃しているものがありますか?

4

1 に答える 1