SQL如何将两列数据透视到不同的列中?

SQL如何将两列数据透视到不同的列中?,sql,sql-server,pivot,Sql,Sql Server,Pivot,这是我的表格: | Scheme Code | MonthYear | Revenue | Revenue2 | |-------------|-----------|---------|----------| | 18VDA | 2018.1 | 100 | 50 | | 18VDA | 2018.2 | 200 | 100 | | 18VDA | 2018.3 | 200 | 150

这是我的表格:

| Scheme Code | MonthYear | Revenue | Revenue2 |
|-------------|-----------|---------|----------|
| 18VDA       | 2018.1    | 100     | 50       |
| 18VDA       | 2018.2    | 200     | 100      |
| 18VDA       | 2018.3    | 200     | 150      |
我想把它转成这样:

| Scheme Code | 2018.1 A | 2018.2 A | 2018.3 A | 2018.1 B | 2018.2 B | 2018.3 B |
|-------------|----------|----------|----------|----------|----------|----------|
| 18VDA       | 100      | 200      | 200      | 50       | 100      | 150      |
| Scheme Code | 2018.1 | 2018.2 | 2018.3 |
|-------------|--------|--------|--------|
| 18VDA       | 100    | 200    | 200    |
我该如何做才能使它在一个月内旋转,但它在收入和收入方面都是重复的2

谢谢

编辑:把我希望的输出表搞砸了!我已经编辑了我想要查看的实际输出表

编辑2:

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

Select @cols = STUFF((SELECT ',' + QUOTENAME([MonthYear]) 
                    from tableA
                    group by [MonthYear]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT *
             FROM ( SELECT [Scheme Code], MonthYear ,[Revenue]
                    FROM TableA
                    ) a
              PIVOT(sum(Revenue) for MonthYear in (' + @cols + ') 
                       ) as RevenueMonth
              ORDER BY [Scheme Code]'    

 execute(@query);
我编写的这段代码只对一列执行此操作,我得到如下输出:

| Scheme Code | 2018.1 A | 2018.2 A | 2018.3 A | 2018.1 B | 2018.2 B | 2018.3 B |
|-------------|----------|----------|----------|----------|----------|----------|
| 18VDA       | 100      | 200      | 200      | 50       | 100      | 150      |
| Scheme Code | 2018.1 | 2018.2 | 2018.3 |
|-------------|--------|--------|--------|
| 18VDA       | 100    | 200    | 200    |

使用
CASE
和动态sql执行此操作

DECLARE @colsA AS NVARCHAR(MAX),
        @colsB AS NVARCHAR(MAX),
        @query AS NVARCHAR(MAX)

select @colsA = (SELECT ', sum(case [MonthYear] when ''' + [MonthYear] + ''' then Revenue end)' + QUOTENAME([MonthYear] + ' A')
                    from tableA
                    group by [MonthYear]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)'),
       @colsB = (SELECT ', sum(case [MonthYear] when ''' + [MonthYear] + ''' then Revenue2 end)' + QUOTENAME([MonthYear] + ' B')
                    from tableA
                    group by [MonthYear]
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)');

Set @query = 'select [Scheme Code]' + @colsA + @colsB + ' from  TableA  group by [Scheme Code] order by [Scheme Code];';
print @query;

我的建议始终是,在深入研究动态SQL之前,首先尝试将查询编写为硬编码或静态版本。这样,您就可以使用较小的数据子集获得所需的最终结果,并且可以验证逻辑是否正确

我将首先执行两个
Revenue
列中的
UNPIVOT
,然后查看如何应用
PIVOT
函数来解决这个问题。要
UNPIVOT
您可以使用
UNPIVOT
功能,也可以使用
CROSS-APPLY
UNION-ALL
将两个
Revenue
列转换为一个列。查询的静态版本与此类似:

select *
from
(
    select 
        t.[Scheme Code],
        new_colname = concat(t.[MonthYear], ' ', r.colname),
        r.colvalue
    from yourtable t
    cross apply
    (
        select 'A', Revenue union all
        select 'B', Revenue2
    ) r (colname, colvalue)
) d
pivot 
(
    sum(colvalue)
    for new_colname in ([2018.1 A], [2018.2 A], [2018.3 A], [2018.1 B], [2018.2 B], [2018.3 B])
) p;
您会注意到,在
交叉应用
中,我添加了一个带有
a
B
的列,用于标识
收入
收入2
列。然后,这将用于为
PIVOT
创建新列名

这将生成您想要的结果。现在要动态地执行此操作,只需将SQL转换为动态代码。您可以使用以下方法获得结果:

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

Select @cols = STUFF((SELECT ',' + QUOTENAME(concat([MonthYear], x.col)) 
                    from yourtable
                    cross join (select col = ' A' union all select ' B') x
                    group by [MonthYear], x.col
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT *
             FROM 
             ( 
                select 
                    t.[Scheme Code],
                    new_colname = concat(t.[MonthYear], '' '', r.colname),
                    r.colvalue
                from yourtable t
                cross apply
                (
                    select ''A'', Revenue union all
                    select ''B'', Revenue2
                ) r (colname, colvalue)
              ) a
              PIVOT
              (
                sum(colvalue) for new_colname in (' + @cols + ') 
              ) as x
              ORDER BY [Scheme Code]';

exec sp_executesql @query;

这两种方法应生成相同的结果()

您使用的是哪种dbms?Microsoft SQL server?注意:2018.3 A在结果表中为300,但输入表中为200。打字错误?没错,很抱歉现在更改了。我编辑了我想要作为输出的表的输出表,前一个表是错误的!对不起,我编辑了我要查找的实际输出表。另外,这只是一个示例表。我有很多日期,从2013年11月一直到2019年6月,所以为所有日期制作案例太难了。@digeridoo,那么你需要一个动态sql。搜索sql dynamic pivot,有很多答案。我可以只为了收入而这样做,但我不确定如何使用dynamic sql为两个字段重复MonthYear。请显示您的代码。基本上,你需要生成另一组列,非常类似于你为Revenuehello所做的,先生,你能帮我回答这个问题吗