【问题标题】:Pivot rows to columns SQL 2008将行透视到列 SQL 2008
【发布时间】:2014-05-22 04:18:57
【问题描述】:

我在这里做了相当多的审查,并且已经接近我需要的东西,但我对最后一点(或者我希望如此)感到困惑。

我正在使用动态数据转置来自

的数据
DocID   PropID  StrVal  NumVal  DateVal
5938    21  TARRO, THOMAS A III NULL    NULL
5938    21  TARRO, JUDITH A NULL    NULL
5938    22  UNITED STATES   NULL    NULL
5938    27  NULL    NULL    2011-10-03 09:33:00.000
5938    28  Discharge Release   NULL    NULL
5938    29  NULL    1115    NULL
5938    30  207 NULL    NULL

到需要的结果

DocId   21  22  27  28  29  30
5938    TARRO, THOMAS A III UNITED STATES   2011-10-03 09:33:00.000 Discharge Release   1115    207
    TARRO, JUDITH A 

这里是代码

Declare @cols as nvarchar(max),
    @query as nvarchar(max)

Select @cols = STUFF ((select distinct ',' + QUOTENAME(FieldName)
                   from GrantorGrantee
                   WHERE tocid='5938'
                   FOR XML Path(''), Type
                   ).value('.','NVARCHAR(MAX)'),1,1,'')

Set @query = 'Select tocid, '+ @cols + 'from
        (
            select fieldname, tocid, FieldStrValue, FieldNumValue,    FieldDateValue
            from GrantorGrantee
         ) x
         PIVOT
         (
            max(FieldStrValue)
             for fieldname in (' +@cols +')
          ) p '

 execute (@query)

这段代码从示例数据中填充了 StrVal,但我需要用每个 PropID 的相应数据填充列...无论是字符串、值还是日期。

来自以下数据:

Tocid     fieldname         StrVal                 NumVal     DateVal
5938      Grantors          Tarro, Thomas A III    NULL       NULL
5938      Grantors          Tarro, Judith A        NULL       NULL
5938      TransactionDate   NULL                   NULL       2011-10-03 09:33:00.00
5938      InstrumentType    Discharge Release      NULL       NULL
5938      BookNumber        NULL                   1115       NULL
5938      PageRange         0207                   NULL       NULL

我可以在数据透视的聚合函数中使用 case 语句吗?这是最好的处理方式吗?我还必须处理 propid = 21 的双精度值...

谢谢!

这是上面代码的结果。

Tocid  BOOKNUMBER Grantees Grantors  InstrumentType    PageRange   TransactionDate    
5938    NULL       UNITED STATES    TARRO, THOMAS A III Discharge Release 0207  NULL
5938    NULL       NULL             NULL    NULL    NULL    NULL
5938    NULL       NULL             NULL    NULL    NULL    NULL

所以我抓取了 StrVal 并填充了列,但 SQL 不知道如何处理 DateVal 和 NumVal...这就是我考虑使用 case 语句的原因。

为了测试旋转源表的整个概念,我在转向动态查询之前对静态查询做了一些工作

这是一个简单的静态查询和来自数据库中的表的结果...这是我用来测试概念的内容...上面的代码使用了一个我可能会或可能不想使用的视图。 ..

select tocid, 21,22,27,28,29,30
from  (
    select tocid, prop_id 
    from dbo.propval
    where dbo.propval.prop_id in (21,22,27,28,29,30) and tocid='5938'
    --order by tocid
     ) x
    PIVOT 
    (
     max(prop_id) 
      for prop_id in ([21],[22],[27],[28],[29],[30]) 
     ) as p

结果如下...没有列标题

5938    21  22  27  28  29  30

这让我走到了那一步……

问题是 PropId 21 在源表中显示为两行,我需要它在生成的数据透视表中显示为两列。

【问题讨论】:

  • 如果您可以添加实际生成的 SQL 及其返回的内容,它会更容易提供帮助。干杯
  • 为什么一开始就这么难?为什么不先写一个 static 查询呢?只需假设一些有限数量的属性并为这些属性编写解决方案。要将结果转换为动态查询,您可能只需遵循与单列透视相同的方法。 “我还必须处理双重价值……”——这是你问题的一部分吗?请说明您希望如何处理。 (从您的示例中不是很清楚。多个值应该进入由某个分隔符分隔的同一行吗?还是不同的行?)另外,您还没有真正展示您自己尝试过的内容...
  • 我已经用一些额外的信息更新了帖子...谢谢!
  • 您在查询中使用的列与示例数据中的列不匹配,它们是否正确或者您可以修复它们吗?
  • 按要求添加数据

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


【解决方案1】:

我知道这已经很晚了,但是如果您还没有弄清楚,here 是一个 SQLfiddle,它可以满足您的要求。从评论的一部分到另一部分,您的列名仍然略有不同,因此我不得不做出一些猜测,并且我确实添加了 1 列来指示每个 propid 的值类型。我敢肯定,您可能会弄清楚如何将其用于您想要做的任何事情(如果您还没有弄清楚或已经放弃了!)无论如何,如果为时已晚,也许它会对您有用别人。

基本上,我将所有值转换为文本,以便 MAX() 聚合可以对所有这些值进行操作,然后使用以与列字符串相同的方式构造的字符串在枢轴之后将它们转换回正确的类型。向数据透视的第一部分添加额外的 ROW_NUMBER() 可以防止将同一 DocID 和 PropID 的多个值聚合为一个。我不确定是否应该为额外的 Grantor 行重复其他字段,所以我展示了两种方式。

【讨论】:

    猜你喜欢
    • 2021-12-27
    • 2021-01-21
    • 1970-01-01
    • 1970-01-01
    • 2016-04-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多