右连接并未从右侧拉入所有行 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