Sql 有人能为这个写查询吗?

Sql 有人能为这个写查询吗?,sql,sql-server,sql-server-2008-r2,pivot,unpivot,Sql,Sql Server,Sql Server 2008 R2,Pivot,Unpivot,我的桌子如下 recordId fwildcardId refNumber wildcardName wildcardValue comments 404450 154834 2 aaa p p 404450 154833 1 aa oi p 406115 15486

我的桌子如下

recordId    fwildcardId refNumber   wildcardName    wildcardValue   comments
404450  154834               2              aaa               p          p
404450  154833               1              aa                oi         p   
406115  154867               1              98                ff        ff
406199  154869               1              aa                aaaa      ssss
406212  154880               1              bbbbb             card      comm
我需要输出为

      RecordId fwildcardid1 refNo1  Name1  Value1 comments1 fwildcardid2 refNo2 Name2 Value2 comments2 fwildcardid3 refNo3 Name3 Value3 comments3 
         404450  154834         2     aaa     p      p        154833       1     aa    oi        p 
         406115   Null         Null   Null   Null   Null      Null        Null   Null   Null   Null   154867        1     98       ff       ff
         406199   Null         Null   Null   Null    Null    154869       1      aa    aaaa     ssss      Null      Null     Null    Null   
我试着像下面那样旋转,但没有成功

select t1.recordId,t1.wildcardid as fwildcardId,t1.refNo as refNumber,t2.wildcardName,t1.attributeValue as wildcardValue,t1.comments 
into #tempp
from fwildcards t1
inner join fwildcardattributes t2 on t2.WildcardID=t1.attributenameid and t2.MarketID=5
inner join fitems t3 on t3.recordid=t1.recordid and t3.marketid=5
order by recordid,attributenameid


select * from #tempp
pivot (min (wildcardValue) for wildcardName in ([aaa],[aa],[aaaa],[98],[kki],[bbbbb],[SUN])) as wildcardValuePivot

为了得到这个结果,您必须取消PIVOT并重新透视数据。UNPIVOT将获取列
fwildcardId
refNumber
wildcarname
wildcardValue
注释中的值,并将它们转换为行。一旦数据成行,就可以应用PIVOT函数来获得最终结果

要取消PIVOT数据,可以使用unpivot函数,也可以使用CROSS APPLY and VALUES子句

UNPIVOT

select recordid,
  col+cast(rn as varchar(10)) col,
  unpiv_value
from
(
  select recordid,
    cast(fwildcardid as varchar(10)) fwildcardid,
    cast(refnumber as varchar(10)) refnumber,
    cast(wildcardname as varchar(10)) name,
    cast(wildcardvalue as varchar(10)) value,
    cast(comments as varchar(10)) comments,
    row_number() over(partition by recordid
                      order by fwildcardid) rn
  from tempp
) d
unpivot
(
  unpiv_value
  for col in (fwildcardid, refnumber, name, value, comments)
) c 

交叉应用和值:

select recordid,
  col+cast(rn as varchar(10)) col,
  value
from
(
  select recordid,
    cast(fwildcardid as varchar(10)) fwildcardid,
    cast(refnumber as varchar(10)) refnumber,
    wildcardname,
    wildcardvalue,
    comments,
    row_number() over(partition by recordid
                      order by fwildcardid) rn
  from tempp
) d
cross apply
(
  values
    ('fwildcardid', fwildcardid),
    ('refnumber', refnumber),
    ('name', wildcardname),
    ('value', wildcardvalue),
    ('comments', comments)
) c (col, value)

将结果转换为以下格式:

| RECORDID |          COL |  VALUE |
------------------------------------
|   404450 | fwildcardid1 | 154833 |
|   404450 |   refnumber1 |      1 |
|   404450 |        name1 |     aa |
|   404450 |       value1 |     oi |
|   404450 |    comments1 |      p |
|   404450 | fwildcardid2 | 154834 |
当您将数据解压到同一列中时,它必须是相同的数据类型。您会注意到,我对列应用了
cast
,因此数据类型相同

数据采用行格式后,可以使用PIVOT将其转换回列:

select *
from
(
  select recordid,
    col+cast(rn as varchar(10)) col,
    unpiv_value
  from
  (
    select recordid,
      cast(fwildcardid as varchar(10)) fwildcardid,
      cast(refnumber as varchar(10)) refnumber,
      cast(wildcardname as varchar(10)) name,
      cast(wildcardvalue as varchar(10)) value,
      cast(comments as varchar(10)) comments,
      row_number() over(partition by recordid
                        order by fwildcardid) rn
    from tempp
  ) d
  unpivot
  (
    unpiv_value
    for col in (fwildcardid, refnumber, name, value, comments)
  ) c 
) src
pivot
(
  max(unpiv_value)
  for col in (fwildcardid1, refnumber1, name1, value1, comments1,
              fwildcardid2, refnumber2, name2, value2, comments2)
) piv;

如果列数已知,则上述版本非常适用,但如果将有未知数量的值转换为列,则需要使用动态sql来获得结果:

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

select @cols = STUFF((SELECT  ',' + QUOTENAME(c.col+cast(rn as varchar(10))) 
                    from
                    (
                      select row_number() over(partition by recordid
                                                order by fwildcardid) rn
                      from tempp
                    ) t
                    cross apply
                    (
                      select 'fwildcardid' col, 1 sortorder union all
                      select 'refNumber', 2 union all
                      select 'name', 3 union all
                      select 'value', 4 union all
                      select 'comments', 5
                    ) c 
                    group by col, rn, sortorder
                    order by rn, sortorder
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT recordid,' + @cols + ' from 
            (
              select recordid,
                col+cast(rn as varchar(10)) col,
                unpiv_value
              from
              (
                select recordid,
                  cast(fwildcardid as varchar(10)) fwildcardid,
                  cast(refnumber as varchar(10)) refnumber,
                  cast(wildcardname as varchar(10)) name,
                  cast(wildcardvalue as varchar(10)) value,
                  cast(comments as varchar(10)) comments,
                  row_number() over(partition by recordid
                                    order by fwildcardid) rn
                from tempp
              ) d
              unpivot
              (
                unpiv_value
                for col in (fwildcardid, refnumber, name, value, comments)
              ) c 
            ) src
            pivot 
            (
                max(unpiv_value)
                for col in (' + @cols + ')
            ) p '

execute(@query);
| RECORDID | FWILDCARDID1 | REFNUMBER1 | NAME1 | VALUE1 | COMMENTS1 | FWILDCARDID2 | REFNUMBER2 |  NAME2 | VALUE2 | COMMENTS2 |
-------------------------------------------------------------------------------------------------------------------------------
|   404450 |       154833 |          1 |    aa |     oi |         p |       154834 |          2 |    aaa |      p |         p |
|   406115 |       154867 |          1 |    98 |     ff |        ff |       (null) |     (null) | (null) | (null) |    (null) |
|   406199 |       154869 |          1 |   kki |   aaaa |      ssss |       (null) |     (null) | (null) | (null) |    (null) |
|   406212 |       154880 |          1 | bbbbb |   card |      comm |       (null) |     (null) | (null) | (null) |    (null) |
看。这两种方法都给出了结果:

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

select @cols = STUFF((SELECT  ',' + QUOTENAME(c.col+cast(rn as varchar(10))) 
                    from
                    (
                      select row_number() over(partition by recordid
                                                order by fwildcardid) rn
                      from tempp
                    ) t
                    cross apply
                    (
                      select 'fwildcardid' col, 1 sortorder union all
                      select 'refNumber', 2 union all
                      select 'name', 3 union all
                      select 'value', 4 union all
                      select 'comments', 5
                    ) c 
                    group by col, rn, sortorder
                    order by rn, sortorder
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT recordid,' + @cols + ' from 
            (
              select recordid,
                col+cast(rn as varchar(10)) col,
                unpiv_value
              from
              (
                select recordid,
                  cast(fwildcardid as varchar(10)) fwildcardid,
                  cast(refnumber as varchar(10)) refnumber,
                  cast(wildcardname as varchar(10)) name,
                  cast(wildcardvalue as varchar(10)) value,
                  cast(comments as varchar(10)) comments,
                  row_number() over(partition by recordid
                                    order by fwildcardid) rn
                from tempp
              ) d
              unpivot
              (
                unpiv_value
                for col in (fwildcardid, refnumber, name, value, comments)
              ) c 
            ) src
            pivot 
            (
                max(unpiv_value)
                for col in (' + @cols + ')
            ) p '

execute(@query);
| RECORDID | FWILDCARDID1 | REFNUMBER1 | NAME1 | VALUE1 | COMMENTS1 | FWILDCARDID2 | REFNUMBER2 |  NAME2 | VALUE2 | COMMENTS2 |
-------------------------------------------------------------------------------------------------------------------------------
|   404450 |       154833 |          1 |    aa |     oi |         p |       154834 |          2 |    aaa |      p |         p |
|   406115 |       154867 |          1 |    98 |     ff |        ff |       (null) |     (null) | (null) | (null) |    (null) |
|   406199 |       154869 |          1 |   kki |   aaaa |      ssss |       (null) |     (null) | (null) | (null) |    (null) |
|   406212 |       154880 |          1 | bbbbb |   card |      comm |       (null) |     (null) | (null) | (null) |    (null) |

无枢轴无交叉应用

根据编辑的问题

select 
DISTINCT
A.recordId AS recordId,
A1.fwildcardId AS fwildcardId1,
A1.refNumber AS refNumber1,
A1.wildcardName AS wildcardName1,
A1.wildcardValue AS wildcardValue1,
A1.comments AS comments1,
A2.fwildcardId AS fwildcardId2,
A2.refNumber AS refNumber2,
A2.wildcardName AS wildcardName2,
A2.wildcardValue AS wildcardValue2,
A2.comments AS comments2,
A3.fwildcardId AS fwildcardId3,
A3.refNumber AS refNumber3,
A3.wildcardName AS wildcardName3,
A3.wildcardValue AS wildcardValue3,
A3.comments AS comments3,
A4.fwildcardId AS fwildcardId4,
A4.refNumber AS refNumber4,
A4.wildcardName AS wildcardName4,
A4.wildcardValue AS wildcardValue4,
A4.comments AS comments4,
A5.fwildcardId AS fwildcardId5,
A5.refNumber AS refNumber5,
A5.wildcardName AS wildcardName5,
A5.wildcardValue AS wildcardValue5,
A5.comments AS comments5,
A6.fwildcardId AS fwildcardId6,
A6.refNumber AS refNumber6,
A6.wildcardName AS wildcardName6,
A6.wildcardValue AS wildcardValue6,
A6.comments AS comments6,
A7.fwildcardId AS fwildcardId7,
A7.refNumber AS refNumber7,
A7.wildcardName AS wildcardName7,
A7.wildcardValue AS wildcardValue7,
A7.comments AS comments7,
A8.fwildcardId AS fwildcardId8,
A8.refNumber AS refNumber8,
A8.wildcardName AS wildcardName8,
A8.wildcardValue AS wildcardValue8,
A8.comments AS comments8,
A9.fwildcardId AS fwildcardId9,
A9.refNumber AS refNumber9,
A9.wildcardName AS wildcardName9,
A9.wildcardValue AS wildcardValue9,
A9.comments AS comments9,
A10.fwildcardId AS fwildcardId10,
A10.refNumber AS refNumber10,
A10.wildcardName AS wildcardName10,
A10.wildcardValue AS wildcardValue10,
A10.comments AS comments10
from Table_name A
LEFt JOIN Table_name A1 ON A.recordId=A1.recordId AND A1.wildcardName='aaa'
LEFT JOIN Table_name A2 ON A.recordId=A2.recordId AND A2.wildcardName='aa'
LEFT JOIN Table_name A3 ON A.recordId=A3.recordId AND A3.wildcardName='98'
LEFT JOIN Table_name A4 ON A.recordId=A4.recordId AND A4.wildcardName=''
LEFT JOIN Table_name A5 ON A.recordId=A5.recordId AND A5.wildcardName=''
LEFT JOIN Table_name A6 ON A.recordId=A6.recordId AND A6.wildcardName=''
LEFT JOIN Table_name A7 ON A.recordId=A7.recordId AND A7.wildcardName=''
LEFT JOIN Table_name A8 ON A.recordId=A8.recordId AND A8.wildcardName=''
LEFT JOIN Table_name A9 ON A.recordId=A9.recordId AND A9.wildcardName=''
LEFT JOIN Table_name A10 ON A.recordId=A10.recordId AND A10.wildcardName=''

重复有任何限制吗?@KuntadyNithesh的可能重复项请看我的答案。我也通过其他方式实现了这一点。但这种方法的问题是,对于不同的记录,它将具有不同的name1值。我的要求是aa应始终命名为1,98应始终命名为2,kki应始终命名为3,依此类推。如果记录没有带aa的通配符,则这些名称的通配符1应为空,类似地,带1的其他字段也应为空,因为记录没有带aa的通配符。@KuntadyNithesh请根据您的问题的完整要求编辑OP。我更新了输出。请看,名称2始终为“aa”。如果记录的名称不为“aa”,则后缀为2的列序列应为空否此查询也不会固定通配符名称position@KuntadyNithesh哥达查。只要给我时间,我就能给出答案。没问题。我会一直努力到你死!此外,请提供4、5、6、7、8、9、10的名称。难以书写的所有内容。但我会说清楚的。假设允许的最大名称数为10。如果记录为m,大于1000,则其名称也将在这10个通配符名称内。一个记录id可以有多个通配符。对于所有记录,特定的通配符名称应位于相同的位置。记录的特定通配符名称不会重复。记录400000不能有两次名为“aa”的通配符。