1

SQLServer2005にはいくつかのテーブルがあります。

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

基本的に、各製品に関連付けられているタグのカテゴリとリストを1行に表示するクエリが必要です。

たとえば、次の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によって返される1つの列にある必要があります。

私はここで似たようなものを見つけました:多くの行を単一のテキスト文字列に連結しますか?

しかし、私はそれをさらに一歩進めて、別々の行に異なるカテゴリを返すのではなく、すべてを1行にまとめる必要があります。

説明するのは難しいですが、あなたがそれを理解することを願っています。

これは可能ですか?

前もって感謝します。

更新:みんなの助けと入力に感謝します。心から感謝する!これが私がこれまでに持っているもので、近いですが、まだ完全にはありません。おそらくそれはあなたが私のためにそれを理解するのを助けるでしょう:D

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

4

3 に答える 3

1

SQLフィドル

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

結果

| ID |      NAME |                                                                 COLUMNNAME |
-----------------------------------------------------------------------------------------------
|  1 | Product 1 | Animals:Bird,Duck,Dog;Countries:Candada,Russia,Japan;Color:Black,Red,White |
于 2013-01-07T22:12:39.870 に答える
0

これは、このデータを1つの文字列にまとめる非常に醜い方法です。ただし、次のようなものを使用できます。

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 FiddlewithDemoを参照してください

結果は次のとおりです。

| 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 FiddlewithDemoを参照してください。これはおそらく、よりクリーンなバージョンにリファクタリングできます。

結果は次のとおりです。

| 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 |
于 2013-01-07T22:08:51.333 に答える
0

サンプルを提供するために、これを試してください。これは、最も簡単なgroup_concat関数を使用してMYSQLで実行されます。使用している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デモ

于 2013-01-07T20:30:51.320 に答える