包含逗号分隔值的sql列

包含逗号分隔值的sql列,sql,sql-server-2008,Sql,Sql Server 2008,如何将多行合并为一行,并使一列包含逗号分隔值 示例:最初,我的SQLresult将使用一个简单的select脚本返回以下内容,如 select order_no, item_no, item_description from orders... order_no item_no item_description 1234 5 toaster 1234 6 hair dryer 相反,我想将结果返回到下面(将项目描述

如何将多行合并为一行,并使一列包含逗号分隔值

示例:最初,我的SQLresult将使用一个简单的select脚本返回以下内容,如

select order_no, item_no, item_description 
from orders...

order_no      item_no  item_description
1234          5        toaster
1234          6        hair dryer
相反,我想将结果返回到下面(将
项目描述
按与
项目编号
相同的顺序列出)

order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 
我可以像这样返回结果吗

order_no    item_nos_descriptions
1234        5 - toaster, 6 - hair dryer

顺便说一下,我正在使用SQL 2008…

如果可以的话,我认为您应该注意@pst

也就是说,大多数关系数据库都有这样的功能。在MySQL中,它是
group\u concat
。在Oracle中,它是
wm\u concat
。在PostgreSQL中,它是
string\u agg
。请注意,它相当不标准

要使用它,您可以执行以下操作:

SELECT order_no, string_agg(item_description, ',') 
FROM orders 
INNER JOIN line_items ON line_item.order_id = order.id
GROUP BY order_no;
order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 
select 
  order_no,
  group_concat( concat(item_no,' - ',item_description 
    ORDER BY item_no ASC SEPARATOR ', ') 
  as item_nos_descriptions
from orders
group by order_no

请注意,并非所有数据库都有从CSV返回到行的方法。我知道PostgreSQL可以做到这一点。我希望Oracle能够做到这一点,但还没有检查,我相当肯定MySQL不能做到,但可能会出错。

如果可以的话,我想你应该注意@pst

也就是说,大多数关系数据库都有这样的功能。在MySQL中,它是
group\u concat
。在Oracle中,它是
wm\u concat
。在PostgreSQL中,它是
string\u agg
。请注意,它相当不标准

要使用它,您可以执行以下操作:

SELECT order_no, string_agg(item_description, ',') 
FROM orders 
INNER JOIN line_items ON line_item.order_id = order.id
GROUP BY order_no;
order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 
select 
  order_no,
  group_concat( concat(item_no,' - ',item_description 
    ORDER BY item_no ASC SEPARATOR ', ') 
  as item_nos_descriptions
from orders
group by order_no

请注意,并非所有数据库都有从CSV返回到行的方法。我知道PostgreSQL可以做到这一点。我希望Oracle能够做到,但还没有检查,而且我相当肯定MySQL不能做到,但可能会出错。

如果您使用MySQL,请尝试
GROUP\u CONCAT

SELECT order_no, 
   GROUP_CONCAT(item_no ORDER BY item_no ASC SEPARATOR ','),
   GROUP_CONCAT(item_description ORDER BY item_no ASC SEPARATOR ',')
FROM Orders
GROUP BY order_no
通过这种方式,您可以保留原始的规范化DB模式,并且仍然可以得到以下结果:

order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 

如果您正在使用mySQL,请尝试
GROUP\u CONCAT

SELECT order_no, 
   GROUP_CONCAT(item_no ORDER BY item_no ASC SEPARATOR ','),
   GROUP_CONCAT(item_description ORDER BY item_no ASC SEPARATOR ',')
FROM Orders
GROUP BY order_no
通过这种方式,您可以保留原始的规范化DB模式,并且仍然可以得到以下结果:

order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 

对于MySQL,您可以这样做:

SELECT order_no, 
   GROUP_CONCAT(CONCAT(item_no,' - ',item_description) ORDER BY item_no ASC SEPARATOR ', ')
FROM Orders
GROUP BY order_no

对于MySQL,您可以这样做:

SELECT order_no, 
   GROUP_CONCAT(CONCAT(item_no,' - ',item_description) ORDER BY item_no ASC SEPARATOR ', ')
FROM Orders
GROUP BY order_no

查看
group\u concat
函数()

将给出如下内容:

SELECT order_no, string_agg(item_description, ',') 
FROM orders 
INNER JOIN line_items ON line_item.order_id = order.id
GROUP BY order_no;
order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 
select 
  order_no,
  group_concat( concat(item_no,' - ',item_description 
    ORDER BY item_no ASC SEPARATOR ', ') 
  as item_nos_descriptions
from orders
group by order_no
对于您请求的第二个表单,它将如下所示:

SELECT order_no, string_agg(item_description, ',') 
FROM orders 
INNER JOIN line_items ON line_item.order_id = order.id
GROUP BY order_no;
order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 
select 
  order_no,
  group_concat( concat(item_no,' - ',item_description 
    ORDER BY item_no ASC SEPARATOR ', ') 
  as item_nos_descriptions
from orders
group by order_no

查看
group\u concat
函数()

将给出如下内容:

SELECT order_no, string_agg(item_description, ',') 
FROM orders 
INNER JOIN line_items ON line_item.order_id = order.id
GROUP BY order_no;
order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 
select 
  order_no,
  group_concat( concat(item_no,' - ',item_description 
    ORDER BY item_no ASC SEPARATOR ', ') 
  as item_nos_descriptions
from orders
group by order_no
对于您请求的第二个表单,它将如下所示:

SELECT order_no, string_agg(item_description, ',') 
FROM orders 
INNER JOIN line_items ON line_item.order_id = order.id
GROUP BY order_no;
order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 
select 
  order_no,
  group_concat( concat(item_no,' - ',item_description 
    ORDER BY item_no ASC SEPARATOR ', ') 
  as item_nos_descriptions
from orders
group by order_no

对于SQLServer2005及以上版本,我通常不使用递归CTE

DECLARE @T TABLE
(
order_no int,
item_no int,
item_description nvarchar(50)
)


INSERT INTO @T VALUES (1234, 5, 'toaster')
INSERT INTO @T VALUES (1234, 6, 'hair dryer')

SELECT order_no,
    STUFF(
        (
            SELECT ', ' + CAST(item_no AS VARCHAR) AS [text()]
            FROM @T As MyItem
            WHERE MyItem.order_no = MyTable.order_no
            FOR XML PATH('')
        ), 1, 2, '' ) AS item_nos,
    STUFF(
        (
            SELECT ', ' + CAST(item_no AS VARCHAR) AS [text()]
            FROM @T As MyItem
            WHERE MyItem.order_no = MyTable.order_no
            FOR XML PATH('')
        ), 1, 2, '' ) AS item_descriptions
FROM @T AS MyTable
GROUP BY order_no
这将产生:

Result Set (1 item)
order_no | item_nos | item_descriptions |
1234     | 5, 6         | 5, 6
填充将从字符串中删除最后一个“,”


另一种方法是使用递归CTE,但我认为上面的方法可以…

对于SQL Server 2005及以上版本,我通常不使用递归CTE

DECLARE @T TABLE
(
order_no int,
item_no int,
item_description nvarchar(50)
)


INSERT INTO @T VALUES (1234, 5, 'toaster')
INSERT INTO @T VALUES (1234, 6, 'hair dryer')

SELECT order_no,
    STUFF(
        (
            SELECT ', ' + CAST(item_no AS VARCHAR) AS [text()]
            FROM @T As MyItem
            WHERE MyItem.order_no = MyTable.order_no
            FOR XML PATH('')
        ), 1, 2, '' ) AS item_nos,
    STUFF(
        (
            SELECT ', ' + CAST(item_no AS VARCHAR) AS [text()]
            FROM @T As MyItem
            WHERE MyItem.order_no = MyTable.order_no
            FOR XML PATH('')
        ), 1, 2, '' ) AS item_descriptions
FROM @T AS MyTable
GROUP BY order_no
这将产生:

Result Set (1 item)
order_no | item_nos | item_descriptions |
1234     | 5, 6         | 5, 6
填充将从字符串中删除最后一个“,”


另一种方法是使用递归CTE,但我认为上面的方法可以…

它闻起来像是一个糟糕的设计。关系数据库被设计为规范化。SQL的哪种风格?SQL Server、MySQL、Postgres、Oracle?我认为这不是模式,而是表示/报告。它闻起来像是一个糟糕的设计。关系数据库被设计为d需要规范化。SQL的哪种风格?SQL Server、MySQL、Postgres、Oracle?我认为这不是架构,而是演示/报告。嗨,我目前正在运行SQL 2008,但我一直收到错误消息“关键字'ORDER'附近的语法不正确”。?嗨,我目前正在运行SQL 2008,但我一直收到错误消息“关键字“ORDER”附近的语法不正确。”?