1

我有三个表和两个日期的范围:

Services
ServicesClients
ServicesClientsDone


@StartDate
@EndDate

服务:

ID | Name
1  | Supervisor
2  | Monitor
3  | Manufacturer

服务客户:

IDServiceClient | IDClient | IDService
1               | 1        | 1
2               | 1        | 2
3               | 2        | 2
4               | 2        | 3

服务客户完成:

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

问题是:如果没有已经完成的服务,我该如何获取客户端上安装的服务和日期范围之间的列表?

4

1 回答 1

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
于 2012-10-23T12:36:56.020 回答