Получить даты, отсутствующие в нескольких диапазонах дат - PullRequest
0 голосов
/ 21 декабря 2018

У меня есть одна таблица, в которой хранится информация о том, когда сотрудник службы поддержки клиентов находится в определенном месте и на какую дату.Каждая отдельная дата является отдельной записью.

У меня есть вторая таблица, в которой хранится диапазон дат, которые клиенты запрашивают на месте поддержки.

Мне нужно извлечь список дат, которые данныйМестоположение НЕ имеет поддержки.Все, что мне нужно, это местоположение и дата (ы).Мне все равно, какой сотрудник в этом месте или какой клиент запросил поддержку.

Поэтому в приведенных ниже примерах данных мне нужно видеть в качестве результатов моего запроса:

+--------+------------+
| London | 04/01/2019 |
| London | 07/01/2019 |
| Paris  | 05/01/2019 |
+--------+------------+

Таблица: Employee_Location

+----------+----------+------------+
| Employee | Location |    Date    |
+----------+----------+------------+
|     1111 | London   | 01/01/2019 |
|     1111 | London   | 02/01/2019 |
|     1111 | London   | 03/01/2019 |
|     2222 | Paris    | 01/01/2019 |
|     2222 | Paris    | 02/01/2019 |
|     2222 | Paris    | 03/01/2019 |
|     2222 | Paris    | 04/01/2019 |
|     3333 | London   | 05/01/2019 |
|     3333 | Paris    | 06/01/2019 |
|     3333 | Paris    | 07/01/2019 |
|     4444 | London   | 06/01/2019 |
+----------+----------+------------+

Таблица: Customer_Request

+----------+----------+---------------+------------+
| Customer | Location | Request From  | Request To |
+----------+----------+---------------+------------+
| AAAA     | London   | 01/01/2019    | 06/01/2019 |
| BBBB     | Paris    | 01/01/2019    | 06/01/2019 |
| CCCC     | London   | 05/01/2019    | 07/01/2019 |
+----------+----------+---------------+------------+

Вот мой текущий код ...

select c.CALENDARDTM 
from CALENDAR c, Employee_Location el 
join Customer_Request cron el.location = cr.location 
where c.CALENDARDTM NOT BETWEEN cr.RequestFrom and cr.RequestTo 
   and c.CALENDARDTM between '2019-01-01' AND '2019-01-07'

1 Ответ

0 голосов
/ 21 декабря 2018

Ключом к решению этой проблемы является создание набора записей, который содержит все даты между назначенными датами начала и окончания.

Существует множество методов, которые можно использовать для этого, в приведенном ниже примере IВы использовали рекурсивный CTE, для больших наборов данных вам нужно будет немного его настроить.

После того, как у вас есть список всех дат, вы объединяете его со списком всех местоположений, поэтому у вас есть все даты на всехlocation.?

Затем вы удаляете все записи, которые соответствуют уже существующим записям, в примере ниже используется «Not Exists», но вы можете использовать различные подходы, чтобы получить желаемый результат.

CREATE TABLE #Employee_Location (Employee int, [Location] varchar(100), [date] date)

INSERT INTO #Employee_Location (Employee, [Location], [Date])
    VALUES   (1111,'London','2019-01-01')
            ,(1111,'London','2019-01-02')
            ,(1111,'London','2019-01-03')
            ,(2222,'Paris','2019-01-01')
            ,(2222,'Paris','2019-01-02')
            ,(2222,'Paris','2019-01-03')
            ,(2222 ,'Paris','2019-01-04')
            ,(3333,'London','2019-01-05')
            ,(3333,'Paris','2019-01-06')
            ,(3333,'Paris','2019-01-07')
            ,(4444,'London','2019-01-06')



DECLARE @StartDate  date    = '2019-01-01'
DECLARE @EndDate    date    = '2019-01-07'

;WITH Dates AS (
    SELECT @StartDate as d
    UNION ALL
    SELECT DateAdd(d, 1, d) as d
    FROM    Dates
    WHERE   d < @EndDate
)
,Locations AS (
    SELECT DISTINCT [Location]
    FROM #Employee_Location
)
,AllRecords AS (
    SELECT  d
            ,[Location]
    FROM    Dates
                FULL OUTER JOIN Locations
                    ON      1=1
)
SELECT  *
FROM    AllRecords
WHERE   NOT EXISTS (SELECT 1 
                    FROM    #Employee_Location  e
                    WHERE   e.[date] = Allrecords.d
                        AND e.[Location] = Allrecords.[Location])
...