右连接并未从右侧拉入所有行 table
Right join isn't pulling in all rows from right table
我在 Microsoft SQL 服务器数据库中有两个用于呼叫中心的表,fact_queue 包含收到的呼叫数量,dim_interval 用于将间隔号 (0-95) 转换为时间戳(例如 07:15-07:30)。它以这种方式设置,因此您可以轻松更改正在提取的时区数据。
我试图得到一个结果,无论是否有电话,它都会显示所有 96 个间隔,但它没有按预期工作。
下面是表格中内容的示例:
Fact_Queue
date_id
queue_id
interval_id
calls_offered
7780
40
0
1
7780
40
2
5
7780
40
3
6
7780
40
5
10
Dim_Interval
interval_id
interval_name
0
00:00 - 00:15
1
00:15 - 00:30
2
00:30 - 00:45
3
00:45 - 01:00
--
--
95
23:45 - 24:00
我试过几个查询变体,我相信下面的查询应该有效,但事实并非如此
SELECT dim_interval.interval_name
,fact_queue.offered_calls
FROM dim_interval
RIGHT JOIN fact_queue
ON fact_queue.interval_id = dim_interval.interval_id
WHERE fact_queue.date_id= '7780'
AND fact_queue.queue_id = '40'
ORDER BY dim_interval.interval_id
这只会导致
interval_name
calls_offered
00:00 - 00:15
1
00:30 - 00:45
5
00:45 - 01:00
6
01:15 - 01:30
10
但我想要的是
interval_name
calls_offered
00:00 - 00:15
1
00:15 - 00:30
null
00:30 - 00:45
5
00:45 - 01:00
6
01:00 - 01:15
null
为什么查询不起作用?如果重要的话,我使用的是 DBeaver 版本 21.0.3.202104181339
在代码段 dim_interval JOIN fact_queue
中,您将维度 table 放在了左侧,而不是右侧。由于您需要维度 table 的所有行,这意味着您需要左外连接...
FROM dim_interval LEFT JOIN fact_queue
不过这只让你完成了一半,因为 WHERE 子句是在连接之后应用的。这意味着 WHERE 子句将过滤掉具有 NULL 的结果。
所以,您需要在加入期间进行过滤...
SELECT dim_interval.interval_name
,fact_queue.offered_calls
FROM dim_interval
LEFT JOIN fact_queue
ON fact_queue.interval_id = dim_interval.interval_id
AND fact_queue.date_id= '7780'
AND fact_queue.queue_id = '40'
ORDER BY dim_interval.interval_id
有些人喜欢在连接之前进行过滤,但这不是必需的,实际上会产生相同的执行计划...
SELECT dim_interval.interval_name
,fact_queue.offered_calls
FROM dim_interval
LEFT JOIN (
SELECT *
FROM fact_queue
WHERE date_id= '7780'
AND queue_id = '40'
) AS fact_queue
ON fact_queue.interval_id = dim_interval.interval_id
ORDER BY dim_interval.interval_id
我在 Microsoft SQL 服务器数据库中有两个用于呼叫中心的表,fact_queue 包含收到的呼叫数量,dim_interval 用于将间隔号 (0-95) 转换为时间戳(例如 07:15-07:30)。它以这种方式设置,因此您可以轻松更改正在提取的时区数据。
我试图得到一个结果,无论是否有电话,它都会显示所有 96 个间隔,但它没有按预期工作。
下面是表格中内容的示例:
Fact_Queue
date_id | queue_id | interval_id | calls_offered |
---|---|---|---|
7780 | 40 | 0 | 1 |
7780 | 40 | 2 | 5 |
7780 | 40 | 3 | 6 |
7780 | 40 | 5 | 10 |
Dim_Interval
interval_id | interval_name |
---|---|
0 | 00:00 - 00:15 |
1 | 00:15 - 00:30 |
2 | 00:30 - 00:45 |
3 | 00:45 - 01:00 |
-- | -- |
95 | 23:45 - 24:00 |
我试过几个查询变体,我相信下面的查询应该有效,但事实并非如此
SELECT dim_interval.interval_name
,fact_queue.offered_calls
FROM dim_interval
RIGHT JOIN fact_queue
ON fact_queue.interval_id = dim_interval.interval_id
WHERE fact_queue.date_id= '7780'
AND fact_queue.queue_id = '40'
ORDER BY dim_interval.interval_id
这只会导致
interval_name | calls_offered |
---|---|
00:00 - 00:15 | 1 |
00:30 - 00:45 | 5 |
00:45 - 01:00 | 6 |
01:15 - 01:30 | 10 |
但我想要的是
interval_name | calls_offered |
---|---|
00:00 - 00:15 | 1 |
00:15 - 00:30 | null |
00:30 - 00:45 | 5 |
00:45 - 01:00 | 6 |
01:00 - 01:15 | null |
为什么查询不起作用?如果重要的话,我使用的是 DBeaver 版本 21.0.3.202104181339
在代码段 dim_interval JOIN fact_queue
中,您将维度 table 放在了左侧,而不是右侧。由于您需要维度 table 的所有行,这意味着您需要左外连接...
FROM dim_interval LEFT JOIN fact_queue
不过这只让你完成了一半,因为 WHERE 子句是在连接之后应用的。这意味着 WHERE 子句将过滤掉具有 NULL 的结果。
所以,您需要在加入期间进行过滤...
SELECT dim_interval.interval_name
,fact_queue.offered_calls
FROM dim_interval
LEFT JOIN fact_queue
ON fact_queue.interval_id = dim_interval.interval_id
AND fact_queue.date_id= '7780'
AND fact_queue.queue_id = '40'
ORDER BY dim_interval.interval_id
有些人喜欢在连接之前进行过滤,但这不是必需的,实际上会产生相同的执行计划...
SELECT dim_interval.interval_name
,fact_queue.offered_calls
FROM dim_interval
LEFT JOIN (
SELECT *
FROM fact_queue
WHERE date_id= '7780'
AND queue_id = '40'
) AS fact_queue
ON fact_queue.interval_id = dim_interval.interval_id
ORDER BY dim_interval.interval_id