我不明白為什么在下面的查詢中必須兩次參考區域表(如 zpu 和 zdo)。當我嘗試使用一個“區域”表修改查詢而不是將其拆分為 zpu 和 zdo 時,我得到了不同的結果。結果表必須有兩列,一列是上車地點,第二列是下車地點。位置包含在“區域”表中。
無法弄清楚為什么會這樣以及我在 SQL 機制中缺乏什么。
表:
旅行
| tpep_pickup_datetime | tpep_dropoff_datetime | 總金額 | PULocationID | DOLocationID |
|---|---|---|---|---|
| “2021-01-01 00:30:10” | “2021-01-01 00:36:12” | 11.8 | 142 | 43 |
| “2021-01-01 00:51:20” | “2021-01-01 00:52:19” | 4.3 | 238 | 151 |
| “2021-01-01 00:43:30” | “2021-01-01 01:11:06” | 51.95 | 132 | 165 |
| “2021-01-01 00:15:48” | “2021-01-01 00:31:01” | 36.35 | 138 | 132 |
| “2021-01-01 00:31:49” | “2021-01-01 00:48:21” | 24.36 | 68 | 33 |
| “2021-01-01 00:16:29” | “2021-01-01 00:24:30” | 14.15 | 224 | 68 |
| “2021-01-01 00:00:28” | “2021-01-01 00:17:28” | 17.3 | 95 | 157 |
| “2021-01-01 00:12:29” | “2021-01-01 00:30:34” | 21.8 | 90 | 40 |
區域
| 位置 ID | 自治市鎮 | 區 |
|---|---|---|
| 1 | EWR | 紐瓦克機場 |
| 2 | 皇后區 | 牙買加灣 |
| 3 | 布朗克斯 | 阿勒頓/佩勒姆花園 |
| 4 | 曼哈頓 | 字母城黃區 |
| 5 | 斯塔滕島 | 雅頓高地 |
| 6 | 斯塔滕島 | 阿羅查爾/沃茲沃思堡 |
| 7 | 皇后區 | 阿斯托利亞 |
| 8 | 皇后區 | 阿斯托利亞公園 |
| 9 | 皇后區 | 奧本代爾 |
| 10 | 皇后區 | 貝斯利公園 |
詢問
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,
zones zpu,
zones zdo
WHERE
t."PULocationID" = zpu."LocationID" AND
t."DOLocationID" = zdo."LocationID"
結果(好表):
| tpep_pickup_datetime | tpep_dropoff_datetime | 總金額 | pick_up_loc | drop_off_loc |
|---|---|---|---|---|
| 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 | 皇后區 / 肯尼迪機場 | Brooklyn / JFK Airport |
| 2021-01-01 00:15:48 | 2021-01-01 00:31:01 | 36.35 | Queens / LaGuardia Airport | Queens / LaGuardia Airport |
| 2021-01-01 00:31:49 | 2021-01-01 00:48:21 | 24.36 | Manhattan / East Chelsea | Brooklyn / East Chelsea |
| 2021-01-01 00:16:29 | 2021-01-01 00:24:30 | 14.15 | Manhattan / Stuy Town/Peter Cooper Village | Manhattan / Stuy Town/Peter Cooper Village |
| 2021-01-01 00:00:28 | 2021-01-01 00:17:28 | 17.3 | Queens / Forest Hills | Queens / Forest Hills |
| 2021-01-01 00:12:29 | 2021-01-01 00:30:34 | 21.8 | Manhattan / Flatiron | Brooklyn / Flatiron |
| 2021-01-01 00:39:16 | 2021-01-01 01:00:13 | 28.8 | Brooklyn / Fort Greene | Queens / Fort Greene |
| 2021-01-01 00:26:12 | 2021-01-01 00:39:46 | 18.95 | Manhattan / Yorkville West | Manhattan / Yorkville West |
uj5u.com熱心網友回復:
您選擇旅行并加入地址,您想知道為什么您被迫再次加入這些地址,以及為什么只告訴 DBMS 一次來獲取地址是不夠的。
您正在使用的古老的連接語法可能會加劇這種誤解——這種語法主要在 1980 年代使用,直到 1992 年顯式連接成為 SQL 標準。
連接表時,實際上是連接表行。
與select * from trips, zones您一起加入每個區域行的每個旅行行。通過 8 個行程行和 10 個區域,您可以獲得 80 個結果行。因此,您每次旅行都加入了所有十個區域。得到select * from trips t, zones zpu, zones zdo800 行的結果,每次行程與所有十個區域相結合,這些再次與所有十個區域相結合,即每次行程所有 100 個可能的區域組合。
在您的查詢中,您有 WHERE t.pulocationid = zpu.locationid AND t.dolocationid = zdo.locationid. 對于一次行程,其 100 個中間結果行中只有一個符合此條件,其他 99 個被忽略。
現在,如果您只加入了區域表一次,則中間結果中每次行程有十行,每行將包含一個區域。現在根據您的標準,有兩個選項:使用AND或OR:
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";
This does exactly the same thing as your query, but it is easier to read. Take a trip, join the pickup location row, join the drop off location row.
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/436632.html
標籤:sql
下一篇:具有重復日期的潛在客戶功能?
