我正在处理包含几天计划的数据库。
我请求发现可能的错误。
我想要一个查询日期的查询。如果缺少日期(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。
答案 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;
答案 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