SQL在一行中按类别连接字符串

时间:2013-01-07 20:02:08

标签: sql sql-server sql-server-2005 string-concatenation

我在SQL Server 2005中有一些表:

  • ProductID, Name
  • CategoryID, Name
  • TagsID, tagName
  • ProductCategoryproductId, tagId
  • CategoryTagscategoryId, tagId

基本上我需要一个查询,它将在一行显示每个产品相关的类别和标签列表。

例如,有3个类别:Animals, Countries, Color

其中每一个都有一堆标签。

让我们说产品1有一堆关联的标签,例如:bird, duck, dog, canada, russia, japan, black, red, white

我需要查询结果格式为:

productId, [Category:tag,tag,tag;Category:tag,tag,tag:Category:tag,tag,tag]

1, [Animal:bird,duck,dog;Country:canada,russia,japan;Color:black,red,white]

方括号中的文本应该在SQL返回的一列中。

我在这里发现了类似的内容:Concatenate many rows into a single text string?

但是我需要更进一步,把它全部放在一行而不是在不同的行上返回不同的类别。

有点难以解释,但希望你明白。

这可能吗?

提前致谢。

更新:感谢大家的帮助和意见。真的很感激! 到目前为止,这是我所接近的,但还不是很接近。也许它会帮助你解决这个问题:D

http://sqlfiddle.com/#!3/eed14/5

4 个答案:

答案 0 :(得分:0)

此stackoverflow答案似乎提供了您正在寻找的解决方案: SQL Server: combining multiple rows into one row

答案 1 :(得分:0)

请举例来试试这个:这是在MYSQL中完成的,它是最简单的group_concat函数......但是。因为你还没有提到你正在使用哪种RDBMS。

select x.productid, group_concat(c.name), 
group_concat(x.tags)
from (
select p.productid, ct.categoryid,
group_concat(t.tagname) as tags
from productcategory p
left join tags t
on t.id = p.tagid
left join  
categorytags ct
on t.id = ct.tagid
group by p.productid, ct.categoryid) x
left join category c
on c.id = x.categoryid
group by x.productid
;

结果:

PRODUCTID   GROUP_CONCAT(C.NAME)    GROUP_CONCAT(X.TAGS)
1       cat1,cat2                   tag2,tag1,tag1
2       cat1                        tag2

SQLFIDDLE DEMO

答案 2 :(得分:0)

将这些数据转换为单个字符串是一种非常难看的方法。但你可以使用这样的东西:

select distinct 
  p.name ProductName,
  STUFF((SELECT distinct ', ' + 
           c.name +':'+ STUFF((SELECT DISTINCT ', ' + Name 
                               FROM tags t
                               LEFT JOIN CategoryTags ct
                                  on t.id = ct.tagid
                               WHERE c.id = ct.categoryid
                               FOR XML PATH('')), 1, 1, '')
         FROM category c 
         LEFT JOIN CategoryTags ct
           ON ct.categoryid = c.id
         LEFT JOIN productcategory pc
           ON pc.tagid = ct.tagid
         WHERE p.id = pc.productid
         FOR XML PATH('')), 1, 1, '')  List
from product p

请参阅SQL Fiddle with Demo

结果是:

| PRODUCTNAME |                                                                               LIST |
----------------------------------------------------------------------------------------------------
|        Test |  Animal: Bird, dog, duck, Color: black, red, white, Country: canada, japan, russia |

编辑#1:这产生了你想要的结果:

select distinct 
  p.name ProductName,
  STUFF((SELECT distinct '; ' + 
           c.name +':'+ STUFF((SELECT DISTINCT ', ' + Name 
                               FROM catalogTags t
                               LEFT JOIN catalogProductTags pt
                                 on t.id = pt.catalogTagId
                               LEFT JOIN catalogCategoryTags ct
                                 on pt.catalogTagId = ct.catalogTagId
                               WHERE c.id = ct.catalogCategoryId
                                  AND p.id = pt.catalogProductId
                               FOR XML PATH('')), 1, 1, '')
         FROM catalogProductTags pt
         LEFT JOIN catalogCategoryTags ct
           ON pt.catalogTagId = ct.catalogTagId
         LEFT JOIN catalogCategory c 
           ON ct.catalogCategoryId = c.id
         WHERE p.id = pt.catalogProductId
         FOR XML PATH('')), 1, 1, '')  List
from catalogProduct p;

SQL Fiddle with Demo。这可能会被重构为更清洁的版本。

结果是:

| PRODUCTNAME |                                                        LIST |
-----------------------------------------------------------------------------
|     tshirt1 |                           Animals: dog; Color: black, white |
|     tshirt2 |              Animals: dog; Color: blue, red; Countries: USA |
|     tshirt3 |  Color: blue, pink, red, white; Countries: Australia, Japan |

答案 3 :(得分:0)

SQL Fiddle

MS SQL Server 2008架构设置

create table Product
(
  ID int, 
  Name varchar(10)
)

create table Category
(
  ID int, 
  Name varchar(10)
)

create table Tags
(
  ID int, 
  Name varchar(10)
)

create table ProductCategory
(
  productId int,
  categoryId int
)

create table CategoryTags
(
  categoryId int, 
  tagId int
)

insert into Product values(1, 'Product 1')

insert into Category values(1, 'Animals')
insert into Category values(2, 'Countries')
insert into Category values(3, 'Color')

insert into Tags values(1, 'Bird') 
insert into Tags values(2, 'Duck') 
insert into Tags values(3, 'Dog') 
insert into Tags values(4, 'Candada') 
insert into Tags values(5, 'Russia') 
insert into Tags values(6, 'Japan') 
insert into Tags values(7, 'Black') 
insert into Tags values(8, 'Red') 
insert into Tags values(9, 'White') 

insert into ProductCategory values(1, 1)
insert into ProductCategory values(1, 2)
insert into ProductCategory values(1, 3)

insert into CategoryTags values(1, 1)
insert into CategoryTags values(1, 2)
insert into CategoryTags values(1, 3)
insert into CategoryTags values(2, 4)
insert into CategoryTags values(2, 5)
insert into CategoryTags values(2, 6)
insert into CategoryTags values(3, 7)
insert into CategoryTags values(3, 8)
insert into CategoryTags values(3, 9)

查询1

select P.ID,
       P.Name,
       (
       select ';'+C.Name+':'+
              (
              select ','+T.Name
              from CategoryTags as CT
                inner join Tags as T
                  on CT.tagId = T.ID
              where CT.categoryId = C.ID
              for xml path(''), type
              ).value('substring(text()[1], 2)', 'varchar(max)') 
       from ProductCategory as PC
         inner join Category as C
           on PC.categoryId = C.ID
       where PC.productId = P.ID
       for xml path(''), type
       ).value('substring(text()[1], 2)', 'varchar(max)') as ColumnName
from Product as P

<强> Results

| ID |      NAME |                                                                 COLUMNNAME |
-----------------------------------------------------------------------------------------------
|  1 | Product 1 | Animals:Bird,Duck,Dog;Countries:Candada,Russia,Japan;Color:Black,Red,White |