我有一个表,用于存储客户支持员工在特定位置的时间以及日期。每个单独的日期都是其自己的记录。
我还有第二张表,其中存储了客户要求现场支持的日期范围。
我需要提取给定位置没有任何支持代表的日期列表。我需要的只是位置和日期。我不在乎那个位置的哪个员工或哪个客户请求支持。
因此,在下面的示例数据中,我需要将其作为查询结果:
+--------+------------+ | 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'
答案 0 :(得分:0)
解决此问题的关键是创建一个记录集,其中包含指定的开始日期和结束日期之间的所有日期。
您可以使用多种方法来执行此操作,在下面的示例中,我使用了递归CTE,对于较大的数据集,您将需要对其进行一些微调。
一旦您拥有所有日期的列表,便可以将其与所有位置的列表结合起来,这样您就可以在所有位置拥有所有日期。
然后,删除与已存在的记录匹配的所有记录,在下面的示例中使用“不存在”,但是您可以使用多种方法来获得所需的结果。
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])