我有一张事实表,我们有OrderId | Arrival_location | Departing_location
。
链接到此的维度表非常基本,类似于LocationID | LocationName
。
要进行查询以获取到达和离开的位置名称,我是否必须join
两次?
SELECT
OrderId, adm.LocationName, dep.LocationName
FROM
fct
LEFT JOIN dim as adm
ON fct.Arrival_location = adm.LocationID
LEFT JOIN dim as dep
ON fct.Departing_location = dep.LocationID
或者只有一个left join
?
答案 0 :(得分:2)
您需要两个联接,因为出发和到达地点是独立值。
让我们稍微重写一下你的查询来说明。我还会将LEFT JOIN
更改为INNER JOIN
,因为这样可以更明确地说明这一点:
SELECT
OrderId, adm.LocationName, dep.LocationName
FROM
fct
INNER JOIN dim
ON fct.Arrival_location = dim.LocationID
AND fct.Departing_location = dim.LocationID
在此查询中,您只加入dim
一次。但你说的是:
fct.Arrival_location = dim.LocationID
fct.Departing_location = dim.LocationID
从逻辑上讲,它遵循以下两个:
fct.Arrival_location = fct.Departing_location
因此,要表达您的查询所需的逻辑,您需要adm.LocationID
和dep.LocationID
代表两个可能不同的 LocationID
值。这在SQL中的工作方式是,通过在同一个表中使用两个不同的别名,您可以获得类似的效果,就好像您有两个相同的表“副本”一样。结果集中的每一行对应于每个“副本”的独立值选择。所以我的查询是这样的:
fct
中的每一行:
dim
中的每一行:而在您的查询中:
fct
中的每一行:
dim
中的每一行,别名为adm
:dim
中的每一行,别名为dep
:LEFT JOIN
部分),则为该组合输出一行。因此,通过额外连接,它会考虑所有组合的位置对。