SQL Server 2012中的group_concat与ORDER BY另一列

时间:2012-11-12 17:39:57

标签: sql-order-by sql-server-2012 sql-server-group-concat

我有一个包含大约一百万个条目的表:

customer_id | purchased_at     | product
1           | 2012-06-01 00:00 | apples
1           | 2012-09-02 00:00 | apples
1           | 2012-10-01 00:00 | pears
2           | 2012-06-01 00:00 | apples
2           | 2012-07-01 00:00 | apples
3           | 2012-09-02 00:00 | pears
3           | 2012-10-01 00:00 | apples
3           | 2012-10-01 01:00 | bananas

我想将产品连接到一行,DISTINCT以及purchase_at的顺序

在MySQL中我只使用

select customer_id, min(purchased_at) as first_purchased_at, 
group_concat(DISTINCT product order by purchased_at) as all_purchased_products
from purchases group by customer_id;

获取

customer_id | first_purchased_at | all_purchased_products
1           | 2012-06-01 00:00 | apples, pears
2           | 2012-06-01 00:00 | apples
3           | 2012-09-02 00:00 | pears, apples, bananas

如何在SQL Server 2012中执行此操作?

我尝试了下面的'hack',这有效,但是它太过分了,在长桌上表现不佳

select
customer_id,
min(purchased_at) as first_purchased_at,
stuff ( ( select  ',' +  p3.product 
          from (select  p2.product, p2.purchased_at, 
          row_number() over(partition by p2.product order by p2.purchased_at) as seq
          from  purchases p2 where
          p2.customer_id = p1.customer_id ) p3 
          where p3.seq = 1 order by p3.purchased_at
          for XML PATH('') ), 1,1,'') AS all_purchased_products  
from purchases p1
group by customer_id;

我该怎么做才能解决这个问题?

1 个答案:

答案 0 :(得分:5)

我不确定这是否会更快,但这是一个替代版本,您不会在purchases STUFF()两次加入select customer_id, min(purchased_at) as first_purchased_at, stuff ((select ',' + p2.product from ( select product, customer_id, ROW_NUMBER() over(partition by customer_id, product order by purchased_at) rn, ROW_NUMBER() over(partition by customer_id order by purchased_at) rnk from purchases ) p2 where p2.customer_id = p1.customer_id and p2.rn = 1 group by p2.product, rn, rnk order by rnk for XML PATH('') ), 1,1,'') AS all_purchased_products from purchases p1 group by customer_id;

| CUSTOMER_ID |               FIRST_PURCHASED_AT | ALL_PURCHASED_PRODUCTS |
---------------------------------------------------------------------------
|           1 |      June, 01 2012 00:00:00+0000 |           apples,pears |
|           2 |      June, 01 2012 00:00:00+0000 |                 apples |
|           3 | September, 02 2012 00:00:00+0000 |   pears,apples,bananas |

请参阅SQL Fiddle with Demo

结果:

{{1}}