Выберите Заявление, чтобы показать отсутствующие записи (Простой вопрос) - PullRequest
2 голосов
/ 30 апреля 2010

Мне нужен T-SQL, который покажет недостающие записи.

Вот некоторые примеры данных:

Emp 1
01/01/2010
02/01/2010
04/01/2010
06/01/2010

Emp 2
02/01/2010
04/01/2010
05/01/2010
etc...

Мне нужно знать

Emp 1 is missing 
03/01/2010
05/01/2010

Emp 2 is missing 
01/01/2010
03/01/2010 
06/01/2010

Диапазон проверки начинается с текущей даты и возвращается на 6 месяцев.

В этом примере предположим, что сегодняшняя дата - 06/12/2010, поэтому диапазон будет с 01.01.2010 по 01.01.2010.

День всегда будет первым в данных.

Спасибо большое. :)

Герхард Вайс
Секретарь Район Великих озер .NET Users Group
GANG Предстоящие встречи | GANG LinkedIn Group

Ответы [ 3 ]

2 голосов
/ 30 апреля 2010

Попробуйте:

DECLARE @Employees table (DateOf datetime, EmployeeID int)
INSERT @Employees VALUES ('01/01/2010',1)
INSERT @Employees VALUES ('02/01/2010',1)
INSERT @Employees VALUES ('04/01/2010',1)
INSERT @Employees VALUES ('06/01/2010',1)
INSERT @Employees VALUES ('02/01/2010',2)
INSERT @Employees VALUES ('04/01/2010',2)
INSERT @Employees VALUES ('05/01/2010',2)

--I was unsure of the data in the question
--this gives first day of each month for last six months
DECLARE @StartDate datetime
       ,@EndDate datetime
SELECT @StartDate=DATEADD(month,-6,DATEADD(month,DATEDIFF(month,0,GETDATE()),0) )
      ,@EndDate=GETDATE()

;with AllDates AS
(
    SELECT @StartDate AS DateOf
    UNION ALL
    SELECT DateAdd(month,1,DateOf)
        FROM AllDates
    WHERE DateOf<@EndDate
)
SELECT
    dt.DateOf,dt.EmployeeID
    FROM (SELECT DISTINCT
              a.DateOf,e.EmployeeID
          FROM AllDates                    a
              CROSS JOIN (SELECT DISTINCT EmployeeID FROM @Employees) e
        ) dt
        LEFT OUTER JOIN @Employees ee ON dt.EmployeeID=ee.EmployeeID AND dt.DateOf=ee.DateOf
    WHERE ee.EmployeeID IS NULL
    ORDER BY dt.EmployeeID,dt.DateOf

ВЫВОД:

DateOf                  EmployeeID
----------------------- -----------
2009-10-01 00:00:00.000 1
2009-11-01 00:00:00.000 1
2009-12-01 00:00:00.000 1
2010-03-01 00:00:00.000 1
2010-05-01 00:00:00.000 1
2009-10-01 00:00:00.000 2
2009-11-01 00:00:00.000 2
2009-12-01 00:00:00.000 2
2010-01-01 00:00:00.000 2
2010-03-01 00:00:00.000 2

(10 row(s) affected)

это будет происходить каждый день в течение последних шести месяцев, просто включите это в вышеприведенное, если это то, что вы хотите:

DECLARE @StartDate datetime
       ,@EndDate datetime
SELECT @StartDate=DATEADD(month,-6,GETDATE())
      ,@EndDate=GETDATE()
;with AllDates AS
(
    SELECT @StartDate AS DateOf
    UNION ALL
    SELECT DateOf+1
        FROM AllDates
    WHERE DateOf<@EndDate
)
SELECT * FROM AllDates
--OPTION (MAXRECURSION 500) --uncomment and increase if the date range needs more rows
1 голос
/ 30 апреля 2010

Если вы возвращаетесь только на фиксированное количество месяцев, вы можете предварительно рассчитать эти даты «первого числа месяца» и оставить соединение с данными вашего сотрудника:

SELECT d.DT, CASE WHEN e.DT IS NULL THEN 1 ELSE 0 END AS IsMissing
FROM (
    SELECT DATEADD(m, DATEDIFF(m, 0, CURRENT_TIMESTAMP), 0) AS DT
    UNION
    SELECT DATEADD(m, DATEDIFF(m, 0, CURRENT_TIMESTAMP) - 1, 0)
    UNION
    SELECT DATEADD(m, DATEDIFF(m, 0, CURRENT_TIMESTAMP) - 2, 0)
    UNION
    SELECT DATEADD(m, DATEDIFF(m, 0, CURRENT_TIMESTAMP) - 3, 0)
    UNION
    SELECT DATEADD(m, DATEDIFF(m, 0, CURRENT_TIMESTAMP) - 4, 0)
    UNION
    SELECT DATEADD(m, DATEDIFF(m, 0, CURRENT_TIMESTAMP) - 5, 0)
) AS d
LEFT JOIN EmployeeDates e ON d.DT = e.DT AND e.EmpID = 1
1 голос
/ 30 апреля 2010

заполните временную таблицу диапазонами дат, а внешнее присоедините временную таблицу к своей таблице Emp * и верните только записи из своей временной таблицы, которые имеют значение NULL в соответствующей строке таблицы Emp *

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...