web-dev-qa-db-ja.com

SQLのすべての列値を連結する

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

クエリは以下を返します:

 FOO 
 ------ 
 RES1 
 
 RES2 
 
 RES3 

今、私は次のような結果が欲しいです:

 FOOCONCAT 
 ----- 
 RES1RES2RES3 

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

26
paweloque

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
47
Quassnoi

QuassnoiのOracleソリューションは非常に印象的ですが、私は foundsimpler MODELマジックではなくSYS_CONNECT_BY_PATH()を使用するものです。

SELECT REPLACE(MAX(SYS_CONNECT_BY_PATH(foo, '/')), '/', '') conc
FROM (
    SELECT T_FOO.*, ROW_NUMBER() OVER (ORDER BY FOO) R FROM T_FOO
)
START WITH r=1
CONNECT BY PRIOR r = r-1;
9
devio

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

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

select @result = @result + RES
from (query goes here)
3
John McLusky

Mysqlの方法:

select group_concat(somecolumn separator '') from sometable
3
ʞɔıu

Edit:バージョン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では、少し簡単に見えます。

1
Eye

あなたが探している答えは次のとおりです。ソリューションは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に置き換えます。

1
Steve Broberg

クエリによって返された列のすべてのレコードをT-SQLの1つのvarchar文字列に連結する方法は? で答えを見つけました

declare @s varchar(8000)
select @s = coalesce(@s + col, col) from tbl

これは解決するはずです

0
navya

文字列の連結は、使用しているデータベースに依存します(質問でバージョンを言及しているため、ここで説明します)...

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 ...確認してください!

:)

0
user110714

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

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;
0
Steve Broberg

SQL Server 2008 R2:

declare @ColumnNameList VARCHAR(MAX)


 SELECT @ColumnNameList  = COALESCE(@ColumnNameList +',' ,'') + ColumnName 
                     FROM 
                       <<table name>>

select @ColumnNameList 
0
Kristy Welsh
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 [〜#〜] を使用します。

0
RedFilter