PIVOT 和 MERGE 的性能 - 有没有更好的方法可以做到这一点?

Performance of PIVOT and MERGE - is there a better way I can do this?

抱歉,这可能有点超出社区的范围,但我想征求第二意见。

我有一个 table 具有以下结构

Table_1 
TYPE    ITEM    DATE        QTYA    QTYB    QTYC
X       AAA     17/08/2015  100     200     300 
X       AAA     18/08/2015  100     170     240 
Y       BBB     17/08/2015  100     240     100

我需要使用此 table 作为合并源,但目标 table 的格式完全不同

Table_2 
ITEM   QTYA_1   QTYA_2......QTYA_31 QTYB_1  QTYB_2  QTYB_3......QTYB_31 QTYC_1  QTYC_2....QTYC_31

(后缀基本上是月份中的某天的数字)

我可以混合使用 UNION ALL 和 PIVOT 将 Table 1 转换为 Table 2 的格式,但性能不是很好 - 特别是因为我必须保存信息在合并之前首先在临时 table 中(Table_1 中的每个 'type' 都有不同的开始日期,我不能从不同的日期开始覆盖 Table_2 中的先前值 - 基本上我必须将 table 与不同的项目类型和不同的开始日期合并 3 或 4 次)

这是我目前得到的结果

SELECT TOP 0 * INTO #TEMP_PIVOT_TABLE
INSERT INTO #TEMP_PIVOT_TABLE SELECT * FROM
    (SELECT ITEM, 'QTYA_' + CONVERT(DATETIMEFROMPARTS(day,DATE) AS VARCHAR) as 'Quantity Type', QTY_A FROM TABLE_1
        UNION_ALL
    SELECT ITEM, 'QTYB_' + CONVERT(DATETIMEFROMPARTS(day,DATE) AS VARCHAR) as 'Quantity Type', QTY_B FROM TABLE_1
        UNION_ALL
    SELECT ITEM, 'QTYC_' + CONVERT(DATETIMEFROMPARTS(day,DATE) AS VARCHAR) as 'Quantity Type', QTY_C FROM TABLE_1
    ) A
    PIVOT
    (SUM(QUANTITY) FOR QUANTITY_TYPE IN ([QTYA_1], [QTYA_2],.....[QTYA_31],[QTYB_1].....[QTYC_31],[QTYC_1].....[QTYC_31])) AS B

----For each different date per item_type, construct a string only selecting those days in the month.
Then merge the results from #TEMP_PIVOT_TABLE into TABLE_2 for each Item TYPE` with dynamic SQL

1) 有没有更好的方法来执行 PIVOT 命令? UNION ALL 命令的性能并不令人鼓舞 - 特别是因为我正在读取的 table 有大量数据。为了简洁起见,我在这里也进行了简化 - 实际 table 需要映射 5 列左右,每列有 31 天

2) MERGE 有没有更好的方法?我不喜欢使用循环 + 动态 SQL 来重复读取相同的数据集,以便在不同的列上合并,但我看不到不同的方式。如此多的列动态构建 MERGE 命令将给以后的维护带来麻烦。

有谁知道我怎样才能更有效地处理这件事?

您可以将 union all 内部查询替换为以下查询。此查询只需要一次 table 命中,而不是为每一列命中 table。

要反转数据,请使用 cross applytable valued constructor

select ITEM,[Quantity Type],QTY 
from yourtable 
cross apply 
(
values 
('QTYA_' + CONVERT(DATEPART(day,DATE) AS VARCHAR),QTY_A),
('QTYB_' + CONVERT(DATEPART(day,DATE) AS VARCHAR),QTY_B),
('QTYC_' + CONVERT(DATEPART(day,DATE) AS VARCHAR),QTY_C),
) 
CS ([Quantity Type],QTY)