为什么引用表两次而不是一次

  • 本文关键字:一次 两次 引用 sql
  • 更新时间 :
  • 英文 :


我不明白为什么在下面的查询中必须两次引用zones表(如zpu和zdo)。当我尝试用一个";区域";表,而不是把它分成zpu和zdo,我有不同的结果。结果表必须有两列,一列带有拾取位置,另一列带有放下位置。位置包含在";区域";桌子

我不明白为什么会这样,我在SQL机制方面缺少什么。

表格:

跳闸

142>td style="text align:centre">43132>td style="text align:central;">16513868>td style="text align:centre">33224>td style="text align:centre">68
tpep_pickup_datetime tpep _dropoff_datetime[/th>total_amount
"2021-01-01 00:30:10"> "2021-01-01 00:36:12"> 11.8
"2021-01-01 00:51:20"> "2021-01-01 00:52:19"> 4.3
"2021-01-01 00:43:30"> "2021-01-01 01:11:06"> 51.95
"2021-01-01 00:15:48"> "2021-01-01 00:31:01"> 36.35
132
"2021-01-01 00:31:49"> "2021-01-01 00:48:21"> 24.36
"2021-01-01 00:16:29"> "2021-01-01 00:24:30"> 14.15
"2021-01-01 00:00:28"> "2021-01-01 00:17:28"> 17.3
"2021-01-01 00:12:29"> "2021-01-01 00:30:34"> 21.8

您选择了行程和联接地址,您想知道为什么您被迫再次联接这些地址,以及为什么只告诉DBMS一次以获取地址还不够。

这种误解可能是由你正在使用的古老的联接语法引起的——这种语法主要在20世纪80年代使用,直到1992年显式联接成为SQL标准。

当您联接表时,您实际上会联接表

使用select * from trips, zones,您可以将每个行程行与每个区域行连接起来。有8个行程行和10个区域,您可以得到80个结果行。所以你每次旅行都加入了所有十个区域。使用select * from trips t, zones zpu, zones zdo,您会得到800行的结果,每个行程与所有十个区域组合,这些区域再次与所有十种区域组合,即每次行程所有100种可能的区域组合。

在您的查询中,您有WHERE t.pulocationid = zpu.locationid AND t.dolocationid = zdo.locationid。对于一个行程,其100个中间结果行中只有一个与该标准匹配,而其他99个被忽略。

现在,如果您只加入一次zones表,那么在您的中间结果中,每次旅行有十行,每行将包含一个zone。现在根据您的标准,有两个选项:使用ANDOR:

select * from trips t, zones z
where t."PULocationID" = z."LocationID" AND t."DOLocationID" = z."LocationID"

这只会选择t.pulocationid=t.dolocationid的行,因为条件要求它们都与连接行中的一个区域匹配。在您的样本数据中,没有一次旅行中两个位置相等。你会得到一个空的结果集。

select * from trips t, zones z
where t."PULocationID" = z."LocationID" OR t."DOLocationID" = z."LocationID"

通过此查询,您将获得区域与t.pulocationid匹配的行和区域与t.dolocationid相匹配的行。也就是说,每次旅行将获得两个结果行,一个与接送区域,一个具有还车区域。

但您希望每次旅行都有一个结果行,两个区域都在同一结果行中。

显式联接使其可读性更强:

select
tpep_pickup_datetime,
tpep_dropoff_datetime,
total_amount,
CONCAT(zpu."Borough", ' / ', zpu."Zone") AS "pick_up_loc",
CONCAT(zdo."Borough", ' / ', zpu."Zone") AS "drop_off_loc"
from trips t
inner join zones zpu on zpu."LocationID" = t."PULocationID"
inner join zones zdo on zdo."LocationID" = t."DOLocationID";

这与查询的作用完全相同,但更易于阅读。来一次旅行,加入取车地点行,加入还车地点行。

最新更新