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 apply
和 table 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)
抱歉,这可能有点超出社区的范围,但我想征求第二意见。
我有一个 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 apply
和 table 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)