30

SQLクエリから返された異なる行のすべての列の値を1つの値に連結する方法は? これは例です:

クエリは次を返します。

フー
------
RES1

RES2

RES3

今、私は次のような結果を得たいと思っています:

フーコンキャット
-----
RES1RES2RES3

SQLでこれを行う方法はありますか?

4

12 に答える 12

51

SQL Server

SELECT  col1 AS [text()]
FROM    foo
FOR XML PATH ('')

MySQL

SELECT  GROUP_CONCAT(col1 SEPARATOR '')
FROM    foo

PostgreSQL

SELECT  array_to_string
        (
        ARRAY
        (
        SELECT  col1
        FROM    foo
        ), ''
        )

Oracle

SELECT  *
FROM    (
        SELECT  col1, ROW_NUMBER() OVER(ORDER BY 1) AS rn
        FROM    foo
        MODEL
        DIMENSION BY
                (rn)
        MEASURES
                (col1, col1 AS group_concat, 0 AS mark)
        RULES UPDATE (
                group_concat[rn > 1] =  group_concat[CV() - 1] || col1[CV()],
                mark[ANY] = PRESENTV(mark[CV() + 1], 0, 1)
                )
        )
WHERE   mark = 1
于 2009-06-09T14:49:37.200 に答える
4

mysql の方法:

select group_concat(somecolumn separator '') from sometable
于 2009-06-09T15:04:01.943 に答える
3

複数の値を持つ 1 つの列であると仮定すると、このアプローチは MS SQL Server で機能します (他のシステムについては言えません)。

declare @result varchar(max)
set @result = ''

select @result = @result + RES
from (query goes here)
于 2009-06-09T15:01:14.663 に答える
1

編集:バージョン 8.4.0 以降、CUBRID はMySQL と90% の互換性を提供します。したがって、MySQL と同様の構文を持つGROUP_CONCATをサポートします。

CREATE TABLE t(i int);
INSERT INTO t VALUES (4),(2),(3),(6),(1),(5);

SELECT GROUP_CONCAT(i*2+1 ORDER BY 1 SEPARATOR '') FROM t;

group_concat(i*2+1 order by 1 separator '')
======================
  '35791113'

かなり強力ですね。以下は、CUBRID でネイティブにサポートされている代替ソリューションです。

SELECT MAX(SYS_CONNECT_BY_PATH(s_name, '')) AS conc_s_name
FROM (
     SELECT ROWNUM AS r, s_name FROM code
) AS res
START WITH r = 1
CONNECT BY PRIOR r = r - 1;

興味深いことに、CUBRID で異なる行の列の値を連結するこの方法は、@devio が提供する Oracle の方法とほとんど同じです。ただし、CUBRID では少し簡単に見えます。

于 2011-03-18T04:31:31.233 に答える
1

これがあなたが探している答えです。解決策は CONNECT BY 操作にあると感じていましたが、以前は SYS_CONNECT_BY_PATH 疑似列を使用したことがありませんでした (ノードへのフルパスをツリーで表示し、ノード名を「/」で区切ります)。以前の「foo」値のセットは、列「myKey」でグループ化されたテーブル内の複数の行であると仮定します。

myKey    foo
-------- ----------
group 1  apple
group 1  orange
group 1  pear
group 2  ape
group 2  bear
group 2  kitten

データをツリー スキーマであるかのように扱い、各グループの値が分岐を下るノードを表していると見なすことができます。その場合、次のようにします。

  SELECT myKey
       , SUBSTR(MAX(REPLACE(SYS_CONNECT_BY_PATH(foo, '/')
                           ,'/'
                           ,' '
                           )
                   )
               ,2
               ) FooConcat
    FROM ( SELECT MyKey
                , Foo
                , row_number() OVER (Partition by myKey order by myKey) NodeDepth
             FROM MyTable
         )
   START WITH NodeDepth = 1
 CONNECT BY PRIOR myKey = myKey
     AND PRIOR NodeDepth = NodeDepth -1
GROUP BY myKey
;

もちろん、連結された値の順序はランダムです。テーブルに、昇順で連続した順序付けフィールドとして使用できる別の列 (「バー」) がある場合は、サブクエリ (ツリーに想像上の深さを設定するためだけに存在する) を省略して、テーブルを直接使用できます。 NodeDepth を bar に置き換えます。

于 2009-06-12T01:21:27.217 に答える
0

文字列の連結は、使用しているデータベースによって異なります(質問でどのバージョンについて言及していないので、ここに行きます)...

OracleおよびDB2では、関数を使用できますCONCAT...CONCAT(string, string)

SQL Server では「+」演算子を使用できます...string1 + string2 + string3

MySQLではCONCAT(string, string... n_string)

最後にPostgreSQLではTEXTCAT(string, string)...

...これは、机の上に置いてあるこの小さなクールな本から得たもので、O'Reilly の SQL Pocket Guide を読んでみてください!

:)

于 2009-06-09T14:54:52.463 に答える
0
select cast(res1 as varchar)+cast(res2 as varchar)+cast(res3 as varchar) as fooconcat from foo

列がすでに文字列である場合、キャストは必要ありません。次のようにするだけです。

select res1 + res2 + res3  as fooconcat from foo

複数の行からのデータには、PIVOTを使用します。

于 2009-06-09T14:46:36.910 に答える
0

あなたが探しているものではないかもしれませんが、私は過去に次のような構造で幸運に恵まれました:

SELECT      MAX(DECODE(fookey, 1, foo, NULL))
         || MAX(DECODE(fookey, 2, foo, NULL))
         || MAX(DECODE(fookey, 3, foo, NULL))
         || MAX(DECODE(fookey, 4, foo, NULL))
       , groupingvalue
    FROM mytable
GROUP BY groupingvalue;

これはプラットフォームに依存せず、foo の値が任意ではあるが限られた数であり、それらが他のキー値に基づいている場合にうまく機能します。たとえば、請求書のテーブルがあり、請求書のすべてのライン タイムを 1 行に連結して表示したい場合、上限は 5 ライン アイテムで、次のようになります。

SELECT      MAX(DECODE(lineno, 1, foo, NULL))
         || ', '
         || MAX(DECODE(lineno, 2, foo, NULL))
         || ', '
         || MAX(DECODE(lineno, 3, foo, NULL))
         || ', '
         || MAX(DECODE(lineno, 4, foo, NULL))
         || ', '
         || MAX(DECODE(lineno, 5, foo, NULL))
       , invoiceid
    FROM lineitem
GROUP BY invoiceid;
于 2009-06-09T15:03:38.483 に答える
-3

[テーブル] から [MyCol] として ([col1] +','+[col2]+','+ [col3]+','+[col4]) を選択します。

于 2010-06-23T11:18:49.593 に答える