【发布时间】:2019-09-05 21:36:49
【问题描述】:
我们有几百万行数据需要通过在started_at 日期和ended_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;
【问题讨论】:
-
在 select 语句中添加 RowNumber,在 where 子句中添加用户 DATEADD(dd, Row_Number Column Value, @pointer)。单个 select 语句可以插入所有行。
-
只需使用一条插入语句即可。这里循环的意义何在?
-
请阅读声明式和命令式语言结构之间的区别。特林是你的答案。切勿在 SQL 声明性语句中使用循环。
-
另外,请不要使用
dd这样的简写形式。输入day并没有更多的努力,但它确实更具可读性(更不用说可靠了)。 -
您正在为日期范围创建天数。在编程语言中,这是通过循环完成的。在 SQL 中,您通常会为此使用递归查询。我现在没有时间发布答案。希望其他人会这样做。
标签: sql sql-server tsql while-loop