【问题标题】:T-SQL (Un)Pivot TableT-SQL(非)数据透视表
【发布时间】:2014-08-07 08:16:44
【问题描述】:

我有一个如下视图(做了一个视图,因为我认为访问更复杂的表会更容易)

ID | aText1 | aText2 | aInt1 | aInt2
-------------------------------------
1  | ABC1   | XYZ1   | 2     |  20
2  | ABC1   | XYZ2   | 3     |  25
3  | ABC2   | XYZ2   | 1     |  30
4  | ABC2   | XYZ1   | 4     |  35

我需要读取结果

       | XYZ1          | XYZ2
aText1 | aInt1 | aInt2 | aInt1 | aInt2 
---------------------------------------
ABC1   | 2     | 20    | 3     | 25
ABC2   | 1     | 30    | 4     | 35

我尝试了各种支点,但都失败了。 aText1aText2 可以是任意数量的值。尽可能接近此解决方案将非常有帮助

【问题讨论】:

  • 我尝试了各种支点,但都失败了请编辑您的问题以显示您的尝试,可能是您的代码中有一些小问题需要更正。

标签: tsql sql-server-2008-r2 pivot unpivot


【解决方案1】:

我通常使用动态sql。像这样的

create table #T
(
    ID int,
    aText1 varchar(4),
    aText2 varchar(4),
    aInt1 int,
    aInt2 int
)

insert into #T
select 1, 'ABC1', 'XYZ1', 2,  20
union
select 2, 'ABC1', 'XYZ2', 3,  25
union
select 3, 'ABC2', 'XYZ2', 1,  30
union
select 4, 'ABC2', 'XYZ1', 4,  35

declare @sql nvarchar(max)

set @sql = 'select aText1 '

select @sql = @sql + ', SUM(case when aText2 = ''' + aText2 + ''' then aInt1 end) as [' + aText2 + ' - aInt1] '+
                     ', SUM(case when aText2 = ''' + aText2 + ''' then aInt2 end) as [' + aText2 + ' - aInt2]'  
from 
(
    select distinct aText2 from #T
) T

set @sql = @sql + ' from #T group by aText1'

exec sp_executeSQL @sql

drop table #T

或者您可以创建另一个视图(如我下一个示例中的#T2)并使用 PIVOT

create table #T
(
    ID int,
    aText1 varchar(4),
    aText2 varchar(4),
    aInt1 int,
    aInt2 int
)

insert into #T
select 1, 'ABC1', 'XYZ1', 2,  20
union
select 2, 'ABC1', 'XYZ2', 3,  25
union
select 3, 'ABC2', 'XYZ2', 1,  30
union
select 4, 'ABC2', 'XYZ1', 4,  35

create table #T2
(
    aText1 varchar(4),
    aText2 varchar(20),
    aValue int
)

insert into #T2
select aText1, aText2 + ' - aInt1' as aText2, aInt1
from #T
union
select aText1, aText2 + ' - aInt2', aInt2 
from #T

declare @sql nvarchar(max), @columns nvarchar(max)
set @columns = ''
select @columns = @columns + ', [' + aText2 + ']'
from (select distinct aText2 from #T2) as T

set @columns = substring(@columns, 2, len(@columns))

set @sql = 
    '
        SELECT *
        FROM
        (SELECT 
                aText1, 
                aText2, 
                aValue 
            FROM 
                #T2 
        ) AS SourceTable
        PIVOT
        (
            SUM(aValue)
            FOR aText2 in ('+@columns+')
        ) AS PivotTable'

exec sp_executeSQL @SQL

drop table #T2
drop table #T

【讨论】:

  • 非常感谢 - 首先,我将如何恢复列名?当然这很明显,但此时我可能无法透过树木看到树林
  • 你想从“XYZ1 - aInt1”中得到“XYZ1”和“aInt1”吗?我通常使用“#”作为列名(“XYZ1#aInt1”)之间的分隔符,然后在我的客户端应用程序中从列名中获取两个子字符串。或者你需要什么把他们带回来?
  • 基本上我得到的输出很好,但最终用户(或我)不知道列名是什么
  • 为什么?我不明白你的意思。在此示例中,最终用户将收到这些列 - “aText1”、“XYZ1 - aInt1”、“XYZ1 - aInt2”、“XYZ2 - aInt1”、“XYZ2 - aInt2”
  • 对不起,我忘了说我会使用 ASP 来输出数据,所以默认情况下它不会输出列,但我希望我应该没问题
猜你喜欢
  • 2012-08-25
  • 2011-11-06
  • 2012-12-28
  • 1970-01-01
  • 2019-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多