11

ある種のウィンドウ関数ですべての行を(グループごとに)連結する方法が必要です。これにより、グループCOUNT(*) OVER(PARTITION BY...)ごとのすべての行の総数が特定のグループごとに繰り返されます。似たようなものが必要ですが、各グループで繰り返されるグループごとのすべての値の文字列連結です。

これが私の問題をよりよく説明するためのいくつかのサンプルデータと私の望ましい結果です:

grp  |  val
------------
1    |  a
1    |  b
1    |  c
1    |  d
2    |  x
2    |  y
2    |  z

そして、これが私が必要とするものです(望ましい結果):

grp  |   val  |  groupcnct
---------------------------------
1    |   a    |  abcd
1    |   b    |  abcd
1    |   c    |  abcd
1    |   d    |  abcd
2    |   x    |  xyz
2    |   y    |  xyz
2    |   z    |  xyz

この問題の本当に難しい部分は次のとおりです。

私の特定の状況では、同じテーブルを2回参照できません(実際には再帰CTE内でこれを行っているため、CTEの自己結合を実行できません。そうしないと、エラーがスローされます)。

私は次のようなことができることを十分に承知しています。

SELECT      a.*, b.groupcnct
FROM        tbl a
CROSS APPLY (
            SELECT STUFF((
                        SELECT '' + aa.val 
                        FROM   tbl aa
                        WHERE  aa.grp = a.grp
                        FOR XML PATH('')
                   ), 1, 0, '') AS groupcnct
            ) b

tbl しかし、ご覧のとおり、これはクエリで2回参照しています。

参照できるのはtbl 1回だけなので、グループ連結のウィンドウ処理が可能かどうか疑問に思うのはなぜですか(MySQLのバックグラウンドを持っているので、TSQLは少し新しいので、そのようなことができるかどうかはわかりません)。


テーブルの作成:

CREATE TABLE tbl
    (grp int, val varchar(1));

INSERT INTO tbl
    (grp, val)
VALUES
    (1, 'a'),
    (1, 'b'),
    (1, 'c'),
    (1, 'd'),
    (2, 'x'),
    (2, 'y'),
    (2, 'z');
4

5 に答える 5

2

SQL 2017 では、STRING_AGG 関数を使用できます。

SELECT STRING_AGG(T.val, ',') AS val
    , T.grp
FROM @tbl AS T
GROUP BY T.grp
于 2018-06-04T13:28:25.563 に答える
1

純粋な CTE アプローチを使用してみました:同じ ID を持つ行を持つテーブルの列を使用して文字列値を形成する最良の方法はどれですか? その方が速いと考える

しかし、ベンチマークは別の方法で、サブクエリ (またはCROSS APPLY) の結果を使用する方XML PATHが高速であることを示しています。

于 2012-08-19T07:37:13.657 に答える