SQL Server“group by”一个连锁查询

时间:2009-06-19 12:06:14

标签: sql-server sql-server-2005 tsql

我需要使用与这些类似的表(实际的简化版本)进行“运行一次”查询(因此性能不是那么关键):

CREATE TABLE #Items
(    ItemPK               int            not null  primary key
    ,ItemDescription      varchar(25)    not null
)

INSERT INTO #Items VALUES (1,'rock')
INSERT INTO #Items VALUES (2,'wood')
INSERT INTO #Items VALUES (3,'plastic')

CREATE TABLE #ItemTypes
(    ItemType             char(1)        not null   primary key
    ,ItemTypeDescription  varchar(25)    not null
)

INSERT INTO #ItemTypes VALUES ('A','Type A')
INSERT INTO #ItemTypes VALUES ('B','BBBBB')
INSERT INTO #ItemTypes VALUES ('C','Color')

CREATE TABLE #ItemInfo
(    InfoPK               int            not null   primary key   identity(1,1)
    ,ItemPK               int            not null   foreign key references #ListOfItems.ItemPK
    ,ItemType             char(1)        not null   foreign key references #ItemTypes.ItemType
    ,ItemValue            varchar(10)    not null
)

INSERT INTO #ItemInfo VALUES (1,'A','hard')
INSERT INTO #ItemInfo VALUES (1,'A','natural')
INSERT INTO #ItemInfo VALUES (1,'B','cold')
INSERT INTO #ItemInfo VALUES (1,'C','gray')
INSERT INTO #ItemInfo VALUES (2,'B','grain')
INSERT INTO #ItemInfo VALUES (2,'B','brown')
INSERT INTO #ItemInfo VALUES (3,'A','flexible')
INSERT INTO #ItemInfo VALUES (3,'A','colorful')
INSERT INTO #ItemInfo VALUES (3,'A','unnatural')
INSERT INTO #ItemInfo VALUES (3,'C','waterproof')

你会收到有关FK和临时表的警告;我只是为了清楚而向他们展示。你可以删除“#”来制作永久表......

当我运行此查询时:

SELECT
    i.ItemDescription
        ,t.ItemTypeDescription
        ,o.ItemValue
    FROM #Items                    i
        LEFT OUTER JOIN #ItemInfo  o ON i.ItemPK=o.ItemPk
        LEFT OUTER JOIN #ItemTypes t ON o.ItemType=t.ItemType

我得到了这个输出:

ItemDescription           ItemTypeDescription       ItemValue
------------------------- ------------------------- ----------
rock                      Type A                    hard
rock                      Type A                    natural
rock                      BBBBB                     cold
rock                      Color                     gray
wood                      BBBBB                     grain
wood                      BBBBB                     brown
plastic                   Type A                    flexible
plastic                   Type A                    colorful
plastic                   Type A                    unnatural
plastic                   Color                     waterproof

但是,我需要输出:

ItemDescription           CombinedDescription
------------------------- -----------------------------------------------
rock                      Type A: hard, natural; BBBBB: cold; Color: gray
wood                      BBBBB: grain, brown
plastic                   Type A: flexible, colorful, unnatural; Color: waterproof


(3 row(s) affected)

感谢...

3 个答案:

答案 0 :(得分:1)

SQL Server中聚合字符串连接的各种选项,由Anita Sen在本文中总结:http://www.simple-talk.com/sql/t-sql-programming/concatenating-row-values-in-transact-sql/

通常最好的选择是XML PATH技巧。

答案 1 :(得分:1)

使用XML技巧,应该这样做:

SELECT      i.ItemDescription,
            (SELECT x.ItemTypeDescription + ': ' + x.vals + 
                CASE WHEN (ROW_NUMBER() OVER (ORDER BY x.ItemType DESC) = 1) THEN '' ELSE '; ' END
                FROM  ( SELECT  DISTINCT
                                ii.ItemPK,
                                t.ItemTypeDescription,
                                ii.ItemType,
                        (SELECT         x.ItemValue + 
                                        CASE WHEN (ROW_NUMBER() OVER (ORDER BY x.ItemValue DESC) = 1) THEN '' ELSE ', ' END
                            FROM        #ItemInfo x
                            WHERE       x.ItemPK = ii.ItemPK
                                    AND x.ItemType = ii.ItemType
                            ORDER BY    x.ItemValue
                            FOR XML PATH('')
                        ) AS VALS
                FROM    #ItemInfo ii
                JOIN    #ItemTypes t
                    ON  ii.ItemType = t.ItemType
                ) x
                WHERE       x.ItemPK = i.ItemPK
                ORDER BY    x.ItemType
                FOR XML PATH('')
            ) AS CombinedDescription

FROM        #Items i

答案 2 :(得分:0)

你可以编写一个标量值函数,它包含一个子查询,它可以在其中执行连接,或者你可以尝试合并,example here