加入时处理丢失的数据
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;
考虑下面的查询
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;