2017-07-03 73 views
0

我正在使用SQL Server 2008.SQL Server - 多列上的XML PATH

我有一个项目表及其所属类别。

----------------------------------------------------------------- 
ItemId | Category1 | Category2 | Category3 | Category4 
----------------------------------------------------------------- 
1  | Val1, Val2 | Val3, Val4 | Val5, Val6 | Val7, Val8 
1  | Val9  |   |   |  
1  | Val10  | Val11  |   | 

* EDIT1

有上表中没有索引和项目Id是不是主键。 每个项目可能属于多个类别。

我想从表中选择不同的ItemId,并将所有可能的类别以逗号分隔为每列。

样本输出 -

------------------------------------------------------------------------------ 
ItemId | Category1    | Category2   | Category3 | Category4 
------------------------------------------------------------------------------ 
1  | Val1, Val2, Val9, Val10 | Val3, Val4, Val11 | Val5, Val6 | Val7, Val8 

我能够做到这一点使用的东西,FOR XML PATH使用下面的查询。但是,我看了一下执行计划,看起来可能不是最好的方法。我为每个分类使用4个不同的SELECT语句。可以将它们合并为一个吗? 我正在寻找最有效的查询来实现与下面的查询相同的结果。

SELECT DISTINCT 
     t1.tblItemId, 
     STUFF((
     SELECT DISTINCT ',' + t2.Category1 
     FROM tblCategory t2 
     WHERE t1.tblItemId = t2.tblItemId 
     FOR XML PATH ('')), 1, 1, '') AS Category1, 
     STUFF((
     SELECT DISTINCT ',' + t2.Category2 
     FROM tblCategory t2 
     WHERE t1.tblItemId = t2.tblItemId 
     FOR XML PATH ('')), 1, 1, '') AS Category2,   
     STUFF((
     SELECT DISTINCT ',' + t2.Category3 
     FROM tblCategory t2 
     WHERE t1.tblItemId = t2.tblItemId 
     FOR XML PATH ('')), 1, 1, '') AS Category3,   
     STUFF((
     SELECT DISTINCT ',' + t2.Category4 
     FROM tblCategory t2 
     WHERE t1.tblItemId = t2.tblItemId 
     FOR XML PATH ('')), 1, 1, '') AS Category4 
FROM tblCategory t1 
where t1.tblItemId IS NOT NULL 

* Edit1 - 当前在逗号分隔的每行中不存在多个值。我已经使用过它们,因为它将来可能是有可能的,没有人会限制它。我正在使用公共表表达式来创建一个临时表,其中包含可用于我的前端的所需输出。

+1

此查询可以使用[query()](https://docs.microsoft.com/en-us/sql/t-sql/xml/query-method -xml-data-type)方法,但性能会比你现在的方法更差.. –

+3

这是一个可怕的数据库设计。阅读[在数据库列中存储分隔列表真的很糟糕吗?](http://stackoverflow.com/questions/3653462/is-storing-a-delimited-list-in-a-database-column-really-that - 巴特),在这里你会看到很多原因,为什么这个问题的答案是**绝对是!** –

+0

嗨Zohar,显示的值是例如目的。虽然逗号分隔值目前不存在,但它可能是一种可能性。我目前正在使用上述查询的公用表表达式。所以在数据库中没有逗号分隔的值。我只是在我的前端制作一张桌子。 – Vishwas

回答