我们需要通过在start_at日期和end_at日期之间的每个日期添加一行来“爆炸”几百万行数据。 while循环是查询中耗时最长的循环。
关于如何优化或替换它的任何想法?
IF (OBJECT_ID('TempDb..#exploded_services') IS NOT NULL)
DROP TABLE #exploded_services;
CREATE TABLE #exploded_services
(
target_date date,
move_id varchar(30),
initiation_id varchar(30),
initiated_at date,
booked_at date,
transferee varchar(60),
account_id varchar(30),
mc_id varchar(30),
po varchar(60),
weight int,
service varchar(150),
started_at date,
ended_at date,
location_id nvarchar(64),
description varchar(max),
provider varchar(max),
mode varchar(60),
origin_location_id nvarchar(64),
destination_location_id nvarchar(64),
transferee_phone varchar(40),
transferee_email varchar(100),
status varchar(10),
ordinal int
);
WHILE (@pointer <= @end_date)
BEGIN
INSERT INTO #exploded_services
SELECT
@pointer,
svcs.*
FROM #Services svcs
WHERE @pointer BETWEEN svcs.started_at AND COALESCE(svcs.ended_at,@end_date)
SET @pointer = DATEADD(dd, 1, @pointer)
END;
答案 0 :(得分:1)
INSERT INTO #exploded_services
SELECT
dates_table.date,
svcs.*
FROM #Services svcs
INNER JOIN dates_table ON dates_table.date BETWEEN svcs.started_at AND COALESCE(svcs.ended_at,_arbitrary_end_date_)
答案 1 :(得分:0)
这可以使用Tally表来实现。这是一个如何使用级联ctes动态创建的示例的示例。
WITH
E(n) AS(
SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0))E(n)
),
E2(n) AS(
SELECT a.n FROM E a, E b
),
E4(n) AS(
SELECT a.n FROM E2 a, E2 b
),
cteTally(n) AS(
SELECT TOP(DATEDIFF(DD, @pointer, @end_date) + 1)
ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1 n
FROM E4
)
INSERT INTO #exploded_services
SELECT
DATEADD( dd, n @pointer),
svcs.*
FROM #Services svcs
JOIN cteTally t ON DATEADD( dd, n @pointer) BETWEEN svcs.started_at AND COALESCE(svcs.ended_at,@end_date);
答案 2 :(得分:0)
您可以尝试使用CTE在下面的代码中生成所需的所有日期:
-- cte to get all dates needed
;with cte as (
select @pointer ptr
union all
select DATEADD(dd, 1, @pointer) from cte
where @pointer < @end_date
)
-- adjusted insert query
INSERT INTO #exploded_services
select c.*, s.*
from #Services s
join cte c on c.ptr between s.started_at and coalesce(svcs.ended_at,@end_date)