SQL查询以检查两个日期之间是否不存在日期

时间:2019-12-17 15:47:30

标签: sql sql-server-2012

我正在处理包含几天计划的数据库。

我请求发现可能的错误。

我想要一个查询日期的查询。如果缺少日期(startDate / endDate)的某一天,我想知道。

例如,如果我数据库中的“天”列包含:

01/01/2019
01/02/2019
01/04/2019

是否可以进行如下查询:

SELECT Day FROM Schedule WHERE Day doesn't exist BETWEEN 01/01/2019 AND 01/04/2019 

我希望它回到我身上01/03/2019。

3 个答案:

答案 0 :(得分:1)

是的,可以(通过日历表或临时查询生成它):

WITH cte AS (
  SELECT CAST('20190101' AS DATETIME) t
  UNION ALL
  SELECT t + 1 AS t
  FROM cte
  WHERE t < '20190104'
)
SELECT c.*
FROM cte c
LEFT JOIN Schedule s
  ON c.t = s.[day]
WHERE s.[day] IS NULL;

db<>fiddle demo

答案 1 :(得分:1)

我的第一个建议是使用您的calendar table,如果您没有,请创建一个。它们非常有用。您的查询就这么简单:

-- DUMMY DATA
WITH Schedule (Day) AS (SELECT CONVERT(DATE, D) FROM (VALUES ('20190101'), ('20190102'), ('20190104')) x (D))

SELECT  Date
FROM    dbo.Calendar AS c
WHERE   c.Date >= '20190101'        -- ADD A START DATE THAT SUITS YOUR NEEDS
AND     c.Date < '20190105'         -- ADD AN END DATE THAT SUITS YOUR NEEDS
AND     NOT EXISTS
        (   SELECT  1
            FROM    Schedule AS s
            WHERE   s.Day = c.Date
        );

如果您不想创建日历表或无法创建日历表,则仍然可以轻松进行以下操作:

DECLARE @StartDate DATE = '2019-01-01',
        @EndDate DATE = GETDATE();

WITH N1 (N) AS (SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
Dates AS
(   SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate) + 1)
            Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY N) - 1, @StartDate)
    FROM N3
)
SELECT  *
FROM    Dates;

这只会产生给定日期范围内所有日期的列表。有关此内容的更多信息,请参见:

然后,您只需要排除存在该日期计划的行:

DECLARE @StartDate DATE = '20190101',
        @EndDate DATE = '20190105';

WITH N1 (N) AS (SELECT 1 FROM (VALUES (1), (1), (1), (1), (1), (1), (1), (1), (1), (1)) n (N)),
N2 (N) AS (SELECT 1 FROM N1 AS N1 CROSS JOIN N1 AS N2),
N3 (N) AS (SELECT 1 FROM N2 AS N1 CROSS JOIN N2 AS N2),
Dates AS
(   SELECT TOP (DATEDIFF(DAY, @StartDate, @EndDate) + 1)
            Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY N) - 1, @StartDate)
    FROM N3
),
-- DUMMY DATA
Schedule (Day) AS (SELECT CONVERT(DATE, D) FROM (VALUES ('20190101'), ('20190102'), ('20190104')) x (D))

SELECT  *
FROM    Dates AS d
WHERE   NOT EXISTS
        (   SELECT  1
            FROM    Schedule AS s
            WHERE   s.Day = d.Date
        );

输出

Date
----------
2019-01-03
2019-01-05

答案 2 :(得分:0)

我将执行以下操作:

1.-获取两个日期之间的天数:

 Set @numberofdays = DATEDIFF(DAY, @StartDate, @EndDate)

2.-获取这些日期之间数据库中的天数并进行比较

if @numberofdays == (select count(distinct(day)) from schedule where days>=@Startdate and days<=@EndDate)
print N'ok'
else
print N'days are missing' 

这是在您只想知道是否缺少日期的情况下,以防您确实需要知道哪些日期可以做

else  
set @currentday = @StartDate
while @currentday < @EndDate
begin
if (select day from schedule where day=@currentday == null)
print @currentday
DATEADD(day, 1, @currentday)
end