从SQL中的复杂选择中连接行

时间:2014-06-21 14:49:50

标签: sql sql-server sql-server-2008 concatenation

RDBMS是SQL Server 2008。

我有3张桌子。为了简化,它们看起来像这样:

NominationOrder表:

NominationOrderId | NominationId
         1        |      5
         2        |      9

NominationOrderItem表:

NominationOrderItemId | NominationOrderId | GiftId
           1          |         1         |    6
           2          |         1         |    3
           3          |         1         |    9

Gift表:

GiftId | GiftName |
  3    |   TVSet
  6    |  TabletPC
  9    | LittlePonny

所以,有一些Nomination。每个Nomination可能有1个Nomination Order。每个Nomination Order可能包含多个Nomination Order Items,每个Gift都会引用此订单中的某些Gift

我正在为Reporting Services报告,我需要在一行中显示每个Gift提名的数据,并显示连接的NominationId | NominationOrderId | GiftName 5 | 1 | TVSet 5 | 1 | TabletPC 5 | 1 | LittlePonny 个名称。

目前它看起来像这样:

NominationId | NominationOrderId |           GiftName
      5      |          1        |   TVSet, TabletPC, LittlePonny

我需要它看起来像这样:

  select 
    nn.NominationId
    ,n_o.NominationOrderId
    ,g.name GiftName
from dbo.Nomination nn
    LEFT JOIN dbo.NominationOrder n_o ON n_o.NominationId = nn.NominationId
    LEFT JOIN dbo.NominationOrderItem noi ON noi.NominationOrderId = n_o.NominationOrderId
    left join dbo.Gift g on g.GiftId = noi.GiftId

当前SQL查询的简化示例:

{{1}}

如何重写它以在单个字符串中输出并连接礼品名称?

2 个答案:

答案 0 :(得分:3)

SELECT result.NominationId, Substring(result.Gifts,3,Len(result.Gifts) - 3)
FROM (
    SELECT 
    NominationId, 
    (SELECT ', ' + CAST(g.GiftName AS varchar(MAX)) 
        FROM NominationOrder i 
        INNER JOIN NominationOrderItem noi on i.NominationOrderId = noi.NominationOrderId
        INNER JOIN Gift g on noi.GiftId = g.GiftId
        WHERE i.NominationId = n.NominationId
        FOR XML PATH (''))
         AS Gifts
    FROM NominationOrder n
    GROUP BY NominationId
) result

答案 1 :(得分:2)

您可以使用CTE:

WITH cteTbl (NominationId, NominationOrderId, GiftName) AS ( Your Query here)

然后使用NominationId将所有行与NominationOrderIdFOR XML PATH('')连接在一起,之后用,替换第一个逗号STUFF

SELECT t.NominationId
     , t.NominationOrderId
     , STUFF( ( SELECT ', ' + GiftName
                FROM cteTbl
                WHERE NominationId = t.NominationId
                  AND NominationOrderId = t.NominationOrderId
                ORDER BY GiftName DESC
                FOR XML PATH('') ), 1, 1, '')
FROM cteTbl t 
GROUP BY t.NominationId
       , t.NominationOrderId

SQLFiddle