我有一个日期维度表。它从1900-01-01开始,包括每天直到2199-12-31的每一天。我需要找到它错过任何日期。
我在互联网上尝试了大多数的查询。我对sql的理解不足以将查询分开理解。另外,我没有写临时表的权限(正在处理临时表),因此这阻碍了某些工作。
这是我尝试过的一个。我的列名是ShortDate。我也尝试比较了一列longdate,但没有尝试。表名是dimDate。
{
SELECT t1.ShortDate AS startOfGap, MIN(t2.ShortDate) AS endOfGap
FROM
(SELECT ShortDate = ShortDate + 1 FROM sampleDates tbl1
WHERE NOT EXISTS(SELECT * FROM [Shared].[dimDates] tbl2
WHERE tbl2.ShortDate = tbl1.ShortDate + 1)
AND ShortDate <> (SELECT MAX(ShortDate) FROM [Shared].[dimDates]))
t1
INNER JOIN
(SELECT ShortDate = ShortDate – 1 FROM [Shared].[dimDates] tbl1
WHERE NOT EXISTS(SELECT * FROM [Shared].[dimDates] tbl2
WHERE tbl1.theDate = tbl2.theDate + 1)
AND ShortDate <> (SELECT MIN(ShortDate) FROM [Shared].
[dimDates])) t2
ON t1.ShortDate <= t2.ShortDate
GROUP BY t1.ShortDate;
}
我尝试的每个查询都会出现很多错误。不幸的是,我的逻辑还不足以理解该查询应包含的内容
我尝试过这个:
SELECT TOP 1
DateShort + 1
FROM [Shared].[dimDates] mo
WHERE NOT EXISTS
(
SELECT NULL
FROM [Shared].[dimDates] mi
WHERE mi.DateShort = mo.DateShort + 1
)
ORDER BY DateShort
但是出现错误,指出“将nvarchar值'2029-10-02'转换为数据类型int时转换失败
答案 0 :(得分:3)
自联接可以与datediff结合使用,以识别缺少日期的间隔。您会明白的。
declare @test table (yourdate datetime);
insert into @test
values
('2019-01-01'),
('2019-01-02'),
('2019-01-03'),
('2019-01-04'),
('2019-01-05'),
('2019-01-07')
select t1.yourdate [firstdate], t2.yourdate [next date],
case when datediff(d,t1.yourdate,t2.yourdate) > 1 then 'flag' else 'ok' end [dayflag]
from
(
select yourdate, row_number() over (order by yourdate) seq
from @test
)t1
left join (select yourdate, row_number() over (order by yourdate) seq from @test) t2
ON t1.seq = t2.seq - 1
答案 1 :(得分:1)
只需使用lead()
:
select sd.*
from (select sd.*, lead(shortdate) over (order by shortdate) as next_shortdate
from sampleDates sd
) sd
where next_shortdate <> dateadd(day, 1, shortdate);
在周期结束时,这不会返回缺少日期的字符串。您可以使用以下方法解决此问题:
where next_shortdate <> dateadd(day, 1, shortdate) or
(next_shortdate is null and shortdate < '2199-12-31'
您也可以使用join
进行此操作:
select sd.* -- the day before each group of missing dates
from sampleDates sd left join
sampleDate sd_next
on sd_next.shortdate = dateadd(day, 1, shortdate)
where sd_next.shortdate is null;
此版本将返回表中的最后一个日期,因此您可能需要添加:
where sd.shortdate < '2199-12-31'