sql列,其中包含逗号单独的值

时间:2011-09-21 05:34:04

标签: sql sql-server-2008

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

示例:最初我的SQLresult将使用简单的选择脚本(如

)返回以下内容
select order_no, item_no, item_description 
from orders...

order_no      item_no  item_description
1234          5        toaster
1234          6        hair dryer

相反,我想将结果返回到下面(将item_description列为与item_nos相同的顺序?

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 ...

5 个答案:

答案 0 :(得分:2)

对于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

STUFF从字符串中删除最后一个','。

另一种方法是使用递归CTE,但我认为上面会做...

答案 1 :(得分:1)

查看group_concat功能(docs)。

select 
  order_no,
  group_concat(item_no ORDER BY item_nos ASC SEPARATOR ', ') as item_nos,
  group_concat(item_description ORDER BY item_no ASC SEPARATOR ', ') 
    as item_descriptions
from orders
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

答案 2 :(得分:0)

如果可以,我认为你应该留意@pst。

尽管如此,大多数关系数据库都具有完成此功能的功能。在MySQL中它是group_concat。在Oracle中它是wm_concat。在PostgreSQL中它是string_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;

请注意,并非所有数据库都有办法从CSV返回行。这是我知道PostgreSQL可以做的事情。我希望Oracle能够做到,但还没有检查过,我很确定MySQL不能,但可能会弄错。

答案 3 :(得分:0)

如果您使用的是mySQL,请尝试GROUP_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

通过这种方式,您可以保留原始的规范化数据库架构,并仍然得到以下结果:

order_no     item_nos    item_descriptions
1234         5, 6        toaster, hair dryer 

答案 4 :(得分:0)

对于MySQL,你可以这样做:

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