2011-09-21 167 views
0

如何将多行组合成一行并且包含逗号分隔值的列?包含逗号分隔值的sql列

例子:本来我SQLRESULT将返回以下使用像

select order_no, item_no, item_description 
from orders... 

order_no  item_no item_description 
1234   5  toaster 
1234   6  hair dryer 

一个简单的选择脚本,而不是我想的结果返回到下面(中具有相同的顺序item_nos列出的item_description

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

+3

它闻起来像一个可怕的设计。关系数据库被设计为规范化的。 – 2011-09-21 05:35:42

+0

SQL有哪些风味? Sql-Server,MySQL,Postgres,Oracle? –

+0

我认为这不是模式,而是演示/报告。 –

回答

1

退房的group_concat函数的n(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 
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可以做的事情。我希望甲骨文能够做到这一点,但没有检查过,而且我相信MySQL不能,但可能会弄错。

0

尝试GROUP_CONCAT如果你正在使用MySQL:

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 
+0

嗨,我目前正在运行SQL 2008,但我不断收到错误消息“关键字'ORDER'附近的语法不正确。”? – HL8

0

对于MySQL,你可以这样做:

SELECT order_no, 
    GROUP_CONCAT(CONCAT(item_no,' - ',item_description) ORDER BY item_no ASC SEPARATOR ', ') 
FROM Orders 
GROUP BY order_no 
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 

东西从字符串删除最后 ''。

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