SQL Server 在 where 子句 中 使用 列 而 不是 字符 串 常量 时 , SQL 查询 将 永远 运行

q1qsirdb  于 2022-11-21  发布在  其他
关注(0)|答案(1)|浏览(130)

我想生成从CustomersHub中的最大日期到其他日期(例如'2022-11-16')的日期范围。
在where子句中使用标量列会导致查询似乎永远运行。我检查了停止条件以确保查询不会无限运行,并且为了测试,我输入了一个常量值,该值基本上与表列的值相同。查询开始运行良好。
下面是两个表:

create table #Temp
(
    dt DateTime,
);

create table CustomersHub
(
    id int,
    firstloadedDate DateTime,
);

下面是我如何将数据插入到临时表中:

insert into #Temp
select top 1 hub.firstloadedDate max_date from CustomersHub hub order by max_date desc;

最后查询生成日期范围:

WITH e00(n)
     AS (SELECT 1
         UNION ALL
         SELECT 1),
     e02(n)
     AS (SELECT 1
         FROM   [e00] [a],
                [e00] [b]),
     e04(n)
     AS (SELECT 1
         FROM   [e02] [a],
                [e02] [b]),
     e08(n)
     AS (SELECT 1
         FROM   [e04] [a],
                [e04] [b]),
     e16(n)
     AS (SELECT 1
         FROM   [e08] [a],
                [e08] [b]),
     e32(n)
     AS (SELECT 1
         FROM   [e16] [a],
                [e16] [b]),
     num_tally(n)
     AS (SELECT Row_number()
                  OVER (
                    ORDER BY ( SELECT NULL) )
         FROM   [e32]),
     tally
     AS (SELECT Dateadd(day, n - 1, dt) dates,
                n,
                dt
         FROM   [num_tally],
                #temp
         WHERE  Datediff(day, dt, '2022-11-16') >= n)
SELECT *
FROM   tally

DROP TABLE #temp

tally cte中,如果我用'2022-10-20'这样的日期替换dt,那么它就可以工作,否则它就一直运行。

lhcgjxsq

lhcgjxsq1#

相反,我会生成一个包含足够多数字的Tally,然后使用DATEADD

DECLARE @FromDate date,
        @ToDate date;

SELECT @FromDate = MAX(hub.firstloadedDate),
       @ToDate = '20221116'
FROM dbo.CustomersHub;

WITH N AS(
    SELECT N
    FROM (VALUES(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL))N(N)),
Tally AS (
    SELECT 0 AS I
    UNION ALL
    SELECT TOP (DATEDIFF(DAY,@FromDate,@ToDate))
           ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS I
    FROM N N1, N N2, N N3, N N4) --Up to 10,000 rows
SELECT DATEADD(DAY, T.I, @FromDate) AS Dt
FROM Tally T;

db<>fiddle

相关问题