我有三张桌子和一系列两个日期:
Services
ServicesClients
ServicesClientsDone
@StartDate
@EndDate
服务:
ID | Name
1 | Supervisor
2 | Monitor
3 | Manufacturer
ServicesClients:
IDServiceClient | IDClient | IDService
1 | 1 | 1
2 | 1 | 2
3 | 2 | 2
4 | 2 | 3
ServicesClientsDone:
IDServiceClient | Period
1 | 201208
3 | 201210
期间= YYYYMM
我需要在@StartDate @EndDate的月份范围内插入ServicesClientsDone。我还有一个临时表(#Periods),其中包含以下列表:
Period
201208
201209
201210
我需要的查询是给我回复以下列表:
IDServiceClient | Period
1 | 201209
1 | 201210
2 | 201208
2 | 201209
2 | 201210
3 | 201208
3 | 201209
4 | 201208
4 | 201209
4 | 201210
哪些是客户服务,但是临时表的排名,而不是那些已经插入的
这就是我所拥有的:
表期间:
DECLARE @i int
DECLARE @mm int
DECLARE @yyyy int,
DECLARE @StartDate datetime
DECLARE @EndDate datetime
set @EndDate = (SELECT GETDATE())
set @StartDate = (SELECT DATEADD(MONTH, -3,GETDATE()))
CREATE TABLE #Periods (Period int)
set @i = 0
WHILE @i <= DATEDIFF(MONTH, @StartDate , @EndDate )
BEGIN
SET @mm= DATEPART(MONTH, DATEADD(MONTH, @i, @FechaInicio))
SET @yyyy= DATEPART(YEAR, DATEADD(MONTH, @i, @FechaInicio))
INSERT INTO #Periods (Period)
VALUES (CAST(@yyyy as varchar(4)) + RIGHT('00'+CONVERT(varchar(6), @mm), 2))
SET @i = @i + 1;
END
ServicesClients与Services之间的关系:
SELECT s.Name, sc.IDClient FROM Services
JOIN ServicesClients AS sc
ON sc.IDService = s.ID
服务已完成且何时:
SELECT s.Name, scd.Period FROM Services
JOIN ServicesClients AS sc
ON sc.IDService = s.ID
JOIN ServicesClientsDone AS scd
ON scd.IDServiceClient = sc.IDServiceClient
问题是:如何在没有服务的情况下获取客户端和日期范围内安装的服务之间的列表?
答案 0 :(得分:1)
使用left join
。
select ServicePeriods.*
from
(
SELECT sc.IDServiceClient, period
FROM Services s
inner join ServicesClients AS sc
cross join #periods
ON sc.IDService = s.ID
) ServicePeriods
left join
(
SELECT scd.IDServiceClient, scd.Period
FROM Services s
INNER JOIN ServicesClients AS sc
ON sc.IDService = s.ID
INNER JOIN ServicesClientsDone AS scd
ON scd.IDServiceClient = sc.IDServiceClient
) exclude
on ServicePeriods.IDServiceClient = exclude.IDServiceClient
and ServicePeriods.Period = exclude.Period
where exclude.IDServiceClient is null
或使用except
查询
SELECT sc.IDServiceClient, period
FROM Services s
INNER JOIN ServicesClients AS sc
cross join periods
ON sc.IDService = s.ID
EXCEPT
SELECT scd.IDServiceClient, scd.Period
FROM Services s
INNER JOIN ServicesClients AS sc
ON sc.IDService = s.ID
INNER JOIN ServicesClientsDone AS scd
ON scd.IDServiceClient = sc.IDServiceClient