Найти недостающие даты в таблице дат Star Schema - PullRequest
1 голос
/ 10 июня 2019

У меня есть таблица измерений дат.Начинается с 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

Ответы [ 2 ]

3 голосов
/ 10 июня 2019

Самостоятельное объединение может использоваться в сочетании с датой для определения пробелов, в которых пропущены дни. Вы поймете идею.

 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 голос
/ 10 июня 2019

Просто используйте 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'
...