加入时处理丢失的数据

Process missing data while joining

考虑下面的查询

DECLARE @DateTimeStart DATETIME
DECLARE @DateTimeEnd DATETIME

SET @dateTimeStart = '2001-04-04'
SET @dateTimeEnd = '2001-04-06'

DECLARE @QH TABLE 
            (
                dt date, 
                QueueName varchar(10)
            )

INSERT INTO @QH (Dt, QueueName)
VALUES ('2001-04-04', 'Queue01'),
       ('2001-04-05', 'Queue01'),
       ('2001-04-06', 'Queue01'),
       ('2001-04-04', 'Queue02'),
       ('2001-04-05', 'Queue02'),
       ('2001-04-06', 'Queue02')

-- SELECT * FROM @QH

DECLARE @SNH TABLE
             (
                 dt date, 
                 QueueName varchar(10),
                 SN varchar(10)
             )

INSERT INTO @SNH (Dt, QueueName, SN)
VALUES ('2001-04-04', 'Queue01', 'Q01SN01'),
       ('2001-04-05', 'Queue01', 'Q01SN01'),
       ('2001-04-06', 'Queue01', 'Q01SN01'),
       ('2001-04-04', 'Queue02', 'Q02SN01'),
       ('2001-04-05', 'Queue02', 'Q02SN01'),
       ('2001-04-06', 'Queue02', 'Q02SN02')

-- SELECT * FROM @SNH

SELECT
    MIN(QHCore.dt) clnStartDate, 
    MAX(QHCore.dt) clnEndDate, 
    QHCore.QueueName AS clnQueueName, 
    SNHStart.SN AS clnSNStart, 
    SNHEnd.SN AS clnSNEnd
FROM    
    @QH QHCore, @QH QHStart, @QH QHEnd, @SNH SNHStart, @SNH SNHEnd
WHERE
    QHCore.QueueName = QHStart.QueueName
    AND QHCore.QueueName = QHEnd.QueueName
    AND QHCore.QueueName = SNHStart.QueueName
    AND QHCore.QueueName = SNHEnd.QueueName
    AND SNHStart.dt = @DateTimeStart
    AND SNHEnd.dt = @DateTimeEnd
GROUP BY 
    QHCore.QueueName, SNHStart.SN, SNHEnd.SN

@DateTimeStart@DateTimeEnd与@SNH table中存在的匹配时,它会选择好看的table,

clnStartDate clnEndDate clnQueueName clnSNStart clnSNEnd
2001-04-04 2001-04-06 Queue01 Q01SN01 Q01SN01
2001-04-04 2001-04-06 Queue02 Q02SN01 Q02SN02

但是如果@SNH 中没有如下对应的条目怎么办

insert into @SNH(Dt, QueueName, SN)
values
--('2001-04-04','Queue01','Q01SN01'),
('2001-04-05','Queue01','Q01SN01'),
('2001-04-06','Queue01','Q01SN01'),
('2001-04-04','Queue02','Q02SN01'),
('2001-04-05','Queue02','Q02SN01'),
('2001-04-06','Queue02','Q02SN02')

则整行未选中

clnStartDate clnEndDate clnQueueName clnSNStart clnSNEnd
2001-04-04 2001-04-06 Queue02 Q02SN01 Q02SN02

那么,有没有办法以某种方式将 Select 转化为结果 table 空值?

如下所示

clnStartDate clnEndDate clnQueueName clnSNStart clnSNEnd
2001-04-04 2001-04-06 Queue01 '' Q01SN01
2001-04-04 2001-04-06 Queue02 Q02SN01 Q02SN02

我认为 @QH@SNH 和 window 函数的 LEFT 联接将执行您想要的操作。

不清楚您是希望将日期限制应用于两个表还是仅应用于 @SNH

如果您想要 @QH 的所有日期,即使它们不在日期限制之间:

SELECT DISTINCT
       MIN(q.Dt) OVER (PARTITION BY q.QueueName) clnStartDate,
       MAX(q.Dt) OVER (PARTITION BY q.QueueName) clnEndDate,
       q.QueueName clnQueueName,    
       FIRST_VALUE(s.SN) OVER (PARTITION BY q.QueueName ORDER BY q.Dt) clnSNStart,
       FIRST_VALUE(s.SN) OVER (PARTITION BY q.QueueName ORDER BY q.Dt DESC) clnSNEnd
FROM @QH q LEFT JOIN @SNH s
ON s.QueueName = q.QueueName AND s.Dt = q.Dt
AND s.Dt BETWEEN @DateTimeStart AND @DateTimeEnd;

如果要对两个表应用限制:

SELECT DISTINCT
       MIN(q.Dt) OVER (PARTITION BY q.QueueName) clnStartDate,
       MAX(q.Dt) OVER (PARTITION BY q.QueueName) clnEndDate,
       q.QueueName clnQueueName,    
       FIRST_VALUE(s.SN) OVER (PARTITION BY q.QueueName ORDER BY q.Dt) clnSNStart,
       FIRST_VALUE(s.SN) OVER (PARTITION BY q.QueueName ORDER BY q.Dt DESC) clnSNEnd
FROM @QH q LEFT JOIN @SNH s
ON s.QueueName = q.QueueName AND s.Dt = q.Dt
WHERE q.Dt BETWEEN @DateTimeStart AND @DateTimeEnd;