concat在sql中的所有列值

时间:2009-06-09 14:45:08

标签: sql concatenation

如何将从sql查询返回的差异行的所有列值连接成一个值?这是一个例子:

查询返回:

FOO
------
RES1

RES2

RES3

现在我希望得到如下结果:

FOOCONCAT
-----
RES1RES2RES3

有没有办法在sql中执行此操作?

12 个答案:

答案 0 :(得分:46)

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

答案 1 :(得分:9)

Quassnoi的Oracle解决方案令人印象深刻,但我found simpler使用SYS_CONNECT_BY_PATH()而不是MODEL魔术。

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;

答案 2 :(得分:3)

假设它是一个具有多个值的列,这种方法适用于MS SQL Server(我不能代表其他系统)。

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

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

答案 3 :(得分:3)

mysql方式:

select group_concat(somecolumn separator '') from sometable

答案 4 :(得分: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
;

当然,连接值的顺序是随机的;如果你的表有另一个列(“bar”)你可以用作升序和连续的排序字段,你可以省去子查询(只存在一个假想的深度到树)并直接使用表,用bar替换NodeDepth。

答案 5 :(得分:1)

编辑:从版本8.4.0开始,CUBRID为90% compatibility提供了MySQL。因此,它支持GROUP_CONCAT,其语法与MySQL相似:

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本身支持的alternative solution

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中,它看起来有点容易。

答案 6 :(得分: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

答案 7 :(得分: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 ...看看吧!

<强>:)

答案 8 :(得分: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的任意但有限数量的值时,它可以正常工作,并且它们基于其他一些键值。例如,如果您有一张发票表,并且希望查看单行上发票的所有行时间,连接,并且您的上限为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;

答案 9 :(得分:0)

SQL Server 2008 R2:

declare @ColumnNameList VARCHAR(MAX)


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

select @ColumnNameList 

答案 10 :(得分:0)

我在How to concatenate all the records in a column returned by a query into one varchar string in T-SQL?

找到了答案
declare @s varchar(8000)
select @s = coalesce(@s + col, col) from tbl

这应解决

答案 11 :(得分:-2)

选择([col1] +','+ [col2] +','+ [col3] +','+ [col4])作为[MyCol]来自[表格]