如何将 sql 查询返回的不同行中的所有列值合并为一个值?这是一个例子:
查询返回:
食品 ------ RES1 RES2 RES3
现在我想得到如下结果:
福康猫 ----- RES1RES2RES3
有没有办法在sql中做到这一点?
如何将 sql 查询返回的不同行中的所有列值合并为一个值?这是一个例子:
查询返回:
食品 ------ RES1 RES2 RES3
现在我想得到如下结果:
福康猫 ----- RES1RES2RES3
有没有办法在sql中做到这一点?
在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
mysql方式:
select group_concat(somecolumn separator '') from sometable
假设它是具有多个值的一列,这种方法适用于 MS SQL Server(我不能代表其他系统)。
declare @result varchar(max)
set @result = ''
select @result = @result + RES
from (query goes here)
这是您正在寻找的答案;我感觉解决方案在于 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。
编辑:由于版本 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 中它看起来更容易一些。
我在如何将查询返回的列中的所有记录连接到 T-SQL 中的一个 varchar 字符串中找到了答案?
declare @s varchar(8000)
select @s = coalesce(@s + col, col) from tbl
这应该解决
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。
连接字符串取决于您使用的数据库(您没有提到问题中的版本,所以这里是)...
在 Oracle 和 DB2 中,您可以使用该CONCAT
功能...CONCAT(string, string)
SQL Server 你可以使用“+”运算符...string1 + string2 + string3
在 MySQL 中是CONCAT(string, string... n_string)
最后在 PostgreSQL 中它是TEXTCAT(string, string)
......
...我从 O'Reilly 的 SQL 袖珍指南中得到了这本很酷的小书...看看吧!
:)
它可能不是你要找的东西,但我过去很幸运,有这样的结构:
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;
SQL Server 2008 R2:
declare @ColumnNameList VARCHAR(MAX)
SELECT @ColumnNameList = COALESCE(@ColumnNameList +',' ,'') + ColumnName
FROM
<<table name>>
select @ColumnNameList
从 [Table] 中选择 ([col1] +','+[col2]+','+ [col3]+','+[col4]) 作为 [MyCol]