2

Я получаю ежедневный txt-файл данных из нескольких антенн. Соглашение об именовании для файлов:Поиск отсутствующих дат в данных

Уникальная антенна ID + год + месяц + день + Random 3-значный номер

Я разобран имена файлов и создали таблицу, как этот:

AntennaID fileyear filemonth fileday filenumber  filename 
0000   2016  09   22   459   000020160922459.txt 
0000   2016  09   21   981   000020160921981.txt 
0000   2016  09   20   762   000020160920762.txt 
0001   2016  09   22   635   000120160922635.txt 
. 
. 
. 
etc. (200k rows) 

Иногда антенны посылают более одного файла или файла вообще. Уникальный 3-значный номер файла отличает файлы, если отправлено более 1, но я пытаюсь найти дни, когда файл не был отправлен.

Я пробовал несколько операторов группы, чтобы сравнить количество файлов данных за данный месяц и посмотреть, совпадает ли это с днями в этом месяце, - но проблема в том, что иногда антенны отправляют более 1 файла за день, который мог бы искусственно компенсировать «недостающий» файл, если мы просто сравниваем счет.

Я ищу более надежный метод поиска дат или диапазонов дат для отсутствующих файлов. Я просмотрел функции Partition and Over и почувствовал, что там может быть потенциал, но я не уверен, как их использовать, поскольку я довольно новичок в SQL.

Я использую Microsoft SQL Server 2016

+0

Это еще один пример того, что называется «Пробелы и Острова ". Вы можете использовать этот термин для множества решений. –

ответ

5

Вы можете использовать common table expression (или cte для краткости), чтобы создать таблицу дат. Затем вы можете join из этой таблицы к данным антенны и искать даты, которые возвращают null значение:

declare @MinDate date = getdate()-50 
declare @MaxDate date = getdate() 

;with Dates as 
(
select @MinDate as DateValue 

union all 

select dateadd(d,1,DateValue) 
from Dates 
where DateValue < @MaxDate 
) 
select d.DateValue 
from Dates d 
    left join AntennaData a 
     on(d.DateValue = cast(cast(a.fileyear as nvarchar(4)) + cast(a.filemonth as nvarchar(4)) + cast(a.fileday as nvarchar(4)) as date)) 
option (maxrecursion 0) 
+1

Мой голос положил вашу репутацию более 1000 человек. Вы должны мне пива. –

+1

@DanBracuk Соблазн пройти вашу историю и проголосовать за 9 вещей, поэтому вы нажмете 15k ... – iamdave

1

Вы можете использовать NOT EXISTS:

DECLARE @BeginDate DATE, @EndDate DATE; 
SET @BeginDate = '20160101'; 
SET @EndDate = '20160922'; 

WITH Dates AS 
(
    SELECT DATEADD(DAY,number,@BeginDate) [Date] 
    FROM master.dbo.spt_values 
    WHERE type = 'P' 
    AND DATEADD(DAY,number,@BeginDate) <= @EndDate 
) 
SELECT * 
FROM Dates A 
WHERE NOT EXISTS(SELECT 1 FROM dbo.Antenna 
       WHERE SUBSTRING([filename],5,8) = A.[Date]); 

 Смежные вопросы

  • Нет связанных вопросов^_^