【问题标题】:pivoting rows to columns in tsql将行旋转到sql中的列
【发布时间】:2012-11-01 20:03:16
【问题描述】:

我有下表和以下示例数据

ID  Language       Question       SubQuestion     SubSubQuestion    TotalCount  TotalPercent
3      E               9               0                1             88527            73%
3      E               9               0                2             19684            16%
3      E               9               0                3             12960            11%
3      E               9               0                9              933              1%

我想要这样的一排

    ID  Language        TotalCount901   TotalPercent901     TotalCount902   TotalPercent902 TotalCount903   TotalPercent903
     3       E            88527           73%                 19684             16%              12960              11%

我已经厌倦了使用 pivot 命令,但它不适合我。

【问题讨论】:

  • “不起作用”是指它会引发错误,给出不想要的结果,还是别的什么?
  • 测试小提琴:sqlfiddle.com/#!3/3a3fc/1
  • 分组标准是什么?子/子子问题的数量是动态的吗?由于需要使用动态生成的 SQL 代码,因此很难使用动态列数进行透视。您是否使用任何类型的应用程序语言来显示可以进行旋转的结果?对于动态列宽方案,这通常更容易。
  • 它有效,但我没有得到我想要的结果。我的逻辑全错了。有需要可以贴代码。 @mellamokb,我相信分组应该是 ID 和 lang。即,我只想要一行用于 ID 和 lang(在我的真实表中,我有许多 id 和许多 lang)。
  • 不,sub/subsub/subsubsub 不是动态的。永远会有他们三个。如果你的意思是价值观,那么也没有!但是它们中有数值

标签: sql sql-server tsql pivot unpivot


【解决方案1】:

我根据您的列名做了一些假设,但看起来您想使用与此类似的东西。这将同时应用 UNPIVOTPIVOT 来获取您请求的列中的值:

select *
from
(
  select id,
    language,
    col + cast(QUESTION as varchar(10))
      +cast(subquestion as varchar(10))
      +cast(SubSubQuestion as varchar(10)) col,
    value
  from
  (
    select id, language,
      cast(TotalCount as varchar(10)) TotalCount, 
      totalPercent,
      question, subquestion, SubSubQuestion
    from yourtable
  ) usrc
  unpivot
  (
    value 
    for col in (totalcount, totalpercent)
  ) un
) srcpiv
pivot
(
  max(value)
  for col in ([TotalCount901], [totalPercent901], 
              [TotalCount902], [totalPercent902], 
              [TotalCount903], [totalPercent903],
              [TotalCount909], [totalPercent909])
) p

SQL Fiddle with Demo

注意:在执行UNPIVOT 时,列需要具有相同的数据类型。如果不是,那么您将需要转换/强制转换以使数据类型相同。

如果你有未知数量的值要转换,你可以使用动态sql:

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


select @colsPivot 
  = STUFF((SELECT  ',' 
             + QUOTENAME(c.name +
                        cast(QUESTION as varchar(10))
                        +cast(subquestion as varchar(10))
                        +cast(SubSubQuestion as varchar(10)))
           from yourtable t
           cross apply sys.columns as C
           where C.object_id = object_id('yourtable') and
              C.name in ('TotalCount', 'TotalPercent')
           group by c.name, t.question, t.subquestion, t.subsubquestion
           order by t.SubSubQuestion
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')


set @query = 'select *
              from
              (
                select id,
                  language,
                  col + cast(QUESTION as varchar(10))
                    +cast(subquestion as varchar(10))
                    +cast(SubSubQuestion as varchar(10)) col,
                  value
                from
                (
                  select id, language,
                    cast(TotalCount as varchar(10)) TotalCount, 
                    totalPercent,
                    question, subquestion, SubSubQuestion
                  from yourtable
                ) usrc
                unpivot
                (
                  value 
                  for col in (totalcount, totalpercent)
                ) un
              ) srcpiv
            pivot 
            (
                max(value)
                for col in (' + @colsPivot + ')
            ) p '

execute(@query)

SQL Fiddle with Demo

【讨论】:

  • +1 很好的答案。我只会建议 OP 似乎忽略了 SubSubQuestion=9 条目。此外,这里证明它也可以处理多个 ID 和语言场景:sqlfiddle.com/#!3/b91b0/1
  • @mellamokb 我也是这么想的,但我认为它是列名的一部分。不确定,因为要求不是 100% 明确的。我只为示例包含了所有值。
  • 我用过你的,但到处都是空值。我会再次查看查询,看看我是否遗漏了什么
  • @masfenix 如果您在查询的PIVOT 部分包含其他字段,您可以获得空值,您必须只包含执行转换所需的字段
  • 我没有添加或删除字段,只是更改了一些名称(因为我的表字段名称有点不同(希望安全且不发布公司数据))。我会更新并让你知道。太感谢了。看起来 sqlfiddle 正是我需要的。编辑:发现错误。多谢你们。哇,漂亮的答案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-10-03
  • 2016-06-16
  • 1970-01-01
  • 2011-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多