繁体   English   中英

SQL 2008将具有相同ID的多行数据合并为一行

[英]SQL 2008 Combining data from multiple rows with the same ID into one row

我在一个表中有数据,其中包含同一CardNum的多行数据。 我想创建一个表,其中同一CardNum的所有数据显示在同一行上。

我的数据目前是这样的:

PartID | CardNumber | RdrGrpID | TZID

0         412         31         1
0         412         34         1
0         567         38         1
0         567         33         5
0         567         71         3

这就是我想要的数据:

PartID | CardNumber | RdrGrpID_1 | TZID_1 | RdrGrpID_2 | TZID_2 | RdrGrpID_3 | TZID_3

0         412         31           1        34           1
0         567         38           1        33           5        71           3

先感谢您。

要获得此结果,您可以通过多种方式来制定查询。

如果每个partIdcardNumber的值都有限,那么可以将row_number()与聚合函数/ CASE组合一起使用:

select partid, cardnumber,
  max(case when rn = 1 then rdrgrpid end) rdrgrpid_1,
  max(case when rn = 1 then TZID end) TZID_1,
  max(case when rn = 2 then rdrgrpid end) rdrgrpid_2,
  max(case when rn = 2 then TZID end) TZID_2,
  max(case when rn = 3 then rdrgrpid end) rdrgrpid_3,
  max(case when rn = 3 then TZID end) TZID_3
from
(
  select partId, cardNumber, RdrGrpID, TZID
      , row_number() over(partition by partiD, cardnumber
                          order by rdrgrpid) rn
  from yt
) d
group by partid, cardnumber;

请参阅SQL Fiddle with Demo

您还可以使用PIVOT / UNPIVOT函数来获得结果:

select *
from
(
  select partid, cardnumber, 
    col+'_'+cast(rn as varchar(10)) col, 
    val
  from 
  (
    select partId, cardNumber, RdrGrpID, TZID
      , row_number() over(partition by partiD, cardnumber
                          order by rdrgrpid) rn
    from yt
  ) d
  unpivot
  (
    val
    for col in (rdrgrpid, tzid)
  ) un
) s
pivot
(
  max(val)
  for col in (RdrGrpID_1, TZID_1, RdrGrpID_2, TZID_2,
              RdrGrpID_3, TZID_3)
) piv

请参阅SQL Fiddle with Demo

现在,如果您有未知数量的值,那么您将需要使用动态sql:

DECLARE @colsPivot AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @colsPivot = STUFF((SELECT ',' + QUOTENAME(c.col + '_'+cast(rn as varchar(10))) 
                    from
                    (
                      select row_number() over(partition by partiD, cardnumber
                                                                    order by rdrgrpid) rn
                      from yt
                    ) t
                    cross apply
                    (
                      select 'RdrGrpID' col, 1 so union all
                      select 'TZID', 2
                    ) c
                    group by col, rn, so
                    order by rn, so
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query 
  = 'select partid, cardnumber,  '+@colsPivot+' 
      from
      (
        select partid, cardnumber, 
          col+''_''+cast(rn as varchar(10)) col, 
          val
        from 
        (
          select partId, cardNumber, RdrGrpID, TZID
            , row_number() over(partition by partiD, cardnumber
                                order by rdrgrpid) rn
          from yt
        ) d
        unpivot
        (
          val
          for col in (rdrgrpid, tzid)
        ) un
      ) s
      pivot
      (
        max(val)
        for col in ('+ @colspivot +')
      ) p'

exec(@query);

请参阅SQL Fiddle with Demo 所有版本都给出了结果:

| PARTID | CARDNUMBER | RDRGRPID_1 | TZID_1 | RDRGRPID_2 | TZID_2 | RDRGRPID_3 | TZID_3 |
-----------------------------------------------------------------------------------------
|      0 |        412 |         31 |      1 |         34 |      1 |     (null) | (null) |
|      0 |        567 |         33 |      5 |         38 |      1 |         71 |      3 |

我会用PIVOT。 以下是第一个Id的示例。 我会对第二个Id做同样的事情,然后加入表格。

SELECT PartID, CardNumber, [1], [2],[3]
FROM
(SELECT  PartID, CardNumber, RdrGrpID, 
         rank() over (partition by CardNumber order by RdrGrpID) r
 FROM [dbo].[Table_1]) AS SourceTable
PIVOT
(
MIN([RdrGrpID])
FOR r IN ([1], [2],[3])
) AS PivotTable;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM