30

如何将 sql 查询返回的不同行中的所有列值合并为一个值?这是一个例子:

查询返回:

食品
------
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 回答
9

Quassnoi 的 Oracle 解决方案令人印象深刻,但我发现 使用 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;
于 2009-06-18T22:38:51.620 回答
4

mysql方式:

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

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

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

select @result = @result + RES
from (query goes here)
于 2009-06-09T15:01:14.663 回答
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。

于 2009-06-12T01:21:27.217 回答
1

编辑:由于版本 8.4.0 CUBRID 提供了与 MySQL 90% 的兼容性。因此,它支持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 原生支持的替代解决方案。

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

我在如何将查询返回的列中的所有记录连接到 T-SQL 中的一个 varchar 字符串中找到了答案

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

这应该解决

于 2018-04-12T14:52:42.203 回答
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

连接字符串取决于您使用的数据库(您没有提到问题中的版本,所以这里是)...

在 Oracle 和 DB2 中,您可以使用该CONCAT功能...CONCAT(string, string)

SQL Server 你可以使用“+”运算符...string1 + string2 + string3

在 MySQL 中是CONCAT(string, string... n_string)

最后在 PostgreSQL 中它是TEXTCAT(string, string)......

...我从 O'Reilly 的 SQL 袖珍指南中得到了这本很酷的小书...看看吧!

:)

于 2009-06-09T14:54:52.463 回答
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;
于 2009-06-09T15:03:38.483 回答
0

SQL Server 2008 R2:

declare @ColumnNameList VARCHAR(MAX)


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

select @ColumnNameList 
于 2015-01-09T21:57:47.793 回答
-3

从 [Table] 中选择 ([col1] +','+[col2]+','+ [col3]+','+[col4]) 作为 [MyCol]

于 2010-06-23T11:18:49.593 回答