Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server通过使用单个取消PIVOT,根据条件组合两行来取消PIVOT表_Sql Server_Row_Conditional Statements_Rows_Unpivot - Fatal编程技术网

Sql server SQL Server通过使用单个取消PIVOT,根据条件组合两行来取消PIVOT表

Sql server SQL Server通过使用单个取消PIVOT,根据条件组合两行来取消PIVOT表,sql-server,row,conditional-statements,rows,unpivot,Sql Server,Row,Conditional Statements,Rows,Unpivot,我有一个大查询,它给出了如下的表结果: [Date] [Type] TC1 TC2 TC3 .......................................... '2014-01-01' T 11 22 33 '2014-01-01' C 44 55 66 '2014-01-02' T 111 222 333 '2014-01-02' C 4

我有一个大查询,它给出了如下的表结果:

[Date]          [Type]  TC1   TC2    TC3
..........................................
'2014-01-01'    T       11    22     33
'2014-01-01'    C       44    55     66
'2014-01-02'    T       111   222    333
'2014-01-02'    C       444   555    666
'2014-01-03'    T       1111  2222   3333
'2014-01-04'    C       4444  5555   6666
[Date]          Cntr      TValue      CValue
............................................
'2014-01-01'    TC1       11          44
'2014-01-01'    TC2       22          55
'2014-01-01'    TC3       33          66
'2014-01-02'    TC1       111         444
'2014-01-02'    TC2       222         555
'2014-01-02'    TC3       333         666
'2014-01-03'    TC1       1111        4444
'2014-01-03'    TC2       2222        5555
'2014-01-03'    TC3       3333        6666
我想让它看起来像这样:

[Date]          [Type]  TC1   TC2    TC3
..........................................
'2014-01-01'    T       11    22     33
'2014-01-01'    C       44    55     66
'2014-01-02'    T       111   222    333
'2014-01-02'    C       444   555    666
'2014-01-03'    T       1111  2222   3333
'2014-01-04'    C       4444  5555   6666
[Date]          Cntr      TValue      CValue
............................................
'2014-01-01'    TC1       11          44
'2014-01-01'    TC2       22          55
'2014-01-01'    TC3       33          66
'2014-01-02'    TC1       111         444
'2014-01-02'    TC2       222         555
'2014-01-02'    TC3       333         666
'2014-01-03'    TC1       1111        4444
'2014-01-03'    TC2       2222        5555
'2014-01-03'    TC3       3333        6666
我成功地做到了这一点,取消了两次激励,然后加入结果。 我提出的问题如下

SELECT A.[Date],A.Cntr,A.TValue,B.CValue
FROM
(
    SELECT [Date],Cntr,TValue
    FROM TB 
    UNPIVOT
    (
    TValue
    FOR Cntr IN (TC1,TC2,TC3)
    ) u
    WHERE  [Type] = 'T' AND u.[Type] = 'T'
) A
JOIN
(
    SELECT [Date],Cntr,CValue
    FROM TB 
    UNPIVOT
    (
    CValue
    FOR Cntr IN (TC1,TC2,TC3)
    ) u
    WHERE  [Type] = 'C' AND u.[Type] = 'C'
) B
ON B.[Date] = A.[Date] AND A.[Cntr] = B.[Cntr]
我的问题是TB表来自一个大而耗时的查询,而且在我的存储过程中,它将被调用数千次,因此我不想在临时表中插入它的许多行,从而浪费宝贵的时间

有没有一种方法可以通过使用一个unpivot或使用更好的方法来解决此问题? 此外,它必须在SQLServer>=2005上运行

SqlFiddle

谢谢大家!

由于(
Date/Type
)在
TB
中被约束为唯一的,因此您可以
UNPIVOT
,然后
PIVOT
避免联接,MAX(Value)是一个任意聚合,因为无论如何只能有一个值

SELECT  pvt.Date,
        pvt.Cntr,
        TValue = pvt.T,
        CValue = pvt.C
FROM    TB
        UNPIVOT (Value FOR Cntr IN (TC1, TC2, TC3)) AS upvt
        PIVOT (MAX(Value) FOR [Type] IN (C, T)) AS pvt;

这将导致读取次数减少一半(正如您可能预期的那样)。IO统计数据显示:

UNPIVOT/PIVOT

表“TB”。扫描计数1,逻辑读取1,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0

UNPIVOT/UNPIVOT/JOIN

表“工作台”。扫描计数0,逻辑读取0,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0

表“TB”。扫描计数2,逻辑读取2,物理读取0,预读0,lob逻辑读取0,lob物理读取0,lob预读0

以及一个更简单的执行计划(顶部为UNPIVOT/PIVOT):

由于(
Date/Type
)在
TB
中被约束为唯一的,因此您可以
UNPIVOT
,然后
PIVOT
避免联接,MAX(Value)是任意聚合,因为无论如何只能有一个值

SELECT  pvt.Date,
        pvt.Cntr,
        TValue = pvt.T,
        CValue = pvt.C
FROM    TB
        UNPIVOT (Value FOR Cntr IN (TC1, TC2, TC3)) AS upvt
        PIVOT (MAX(Value) FOR [Type] IN (C, T)) AS pvt;

这将导致读取次数减少一半(正如您可能预期的那样)。IO统计数据显示:

UNPIVOT/PIVOT

表“TB”。扫描计数1,逻辑读取1,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0

UNPIVOT/UNPIVOT/JOIN

表“工作台”。扫描计数0,逻辑读取0,物理读取0,预读读取0,lob逻辑读取0,lob物理读取0,lob预读读取0

表“TB”。扫描计数2,逻辑读取2,物理读取0,预读0,lob逻辑读取0,lob物理读取0,lob预读0

以及一个更简单的执行计划(顶部为UNPIVOT/PIVOT):


一种方法是使用交叉应用和条件聚合:

select [date], [cntr],
       max(case when [type] = 'T' then val end) as TValue,
       max(case when [type] = 'C' then val end) as CValue
from (<your query here>) t cross apply
     (values ([date], [type], 'tc1', tc1),
             ([date], [type], 'tc2', tc2),
             ([date], [type], 'tc3', tc3)
     ) vals([date], [type], cntr, val)
group by [date], [cntr];

一种方法是使用交叉应用和条件聚合:

select [date], [cntr],
       max(case when [type] = 'T' then val end) as TValue,
       max(case when [type] = 'C' then val end) as CValue
from (<your query here>) t cross apply
     (values ([date], [type], 'tc1', tc1),
             ([date], [type], 'tc2', tc2),
             ([date], [type], 'tc3', tc3)
     ) vals([date], [type], cntr, val)
group by [date], [cntr];

日期/类型在TB中是否被限制为唯一?如果不是,即在一个日期有两条类型为
T
的记录和两条类型为“C”的记录,那么您如何在不创建笛卡尔积的情况下匹配每一条T和C,或者笛卡尔积是所需的结果?很抱歉理解错误!是的,日期和类型将始终是唯一的。日期/类型在TB中是否被限制为唯一?如果不是,即在一个日期有两条类型为
T
的记录和两条类型为“C”的记录,那么您如何在不创建笛卡尔积的情况下匹配每一条T和C,或者笛卡尔积是所需的结果?很抱歉理解错误!是的,日期和类型总是唯一的谢谢你的快速回答。我不会想到这个解决方案。我将在我的SP中使用它,因为它的性能更好!谢谢你的快速回答。我不会想到这个解决方案。我将在我的SP中使用它,因为它的性能更好!我曾想过交叉申请,但泰国工会全体成员都支持我。不过我会尝试一下:)我曾想过交叉申请,但泰国工会全体支持我。不过我会试试看:)