如何在 MySQL 中從多個表中進行選擇
本教程介紹瞭如何在一個指令碼中使用 MySQL 從多個表中查詢 SELECT。
讓我們演示一種情況:
SELECT name, price, details, type, FROM food, food_order WHERE breakfast.id = 'breakfast_id'
現在,讓我們想象一下每個 FROM 條目的示例表。
food
| food_id | name | price | options |
|---|---|---|---|
| 1 | Eggs | 10.00 | Scrambled, Sunny Side, Boiled |
| 2 | Ice cream | 30.00 | Vanilla, Strawberry, Chocolate |
| 3 | Ramen | 12.00 | Regular, Spicy |
food_menu
| order_id | photo | food_id |
|---|---|---|
| 1 | eggs_scrambled.jpg | 1 |
| 2 | eggs_sunnyside.jpg | 1 |
| 3 | eggs_boiled.png | 1 |
| 4 | icecream_vanilla.jpg | 2 |
| 5 | icecream_strawberry.jpg | 2 |
| 6 | ice_cream_chocolate.jpg | 2 |
| 7 | ramen_regular.jpg | 3 |
| 8 | ramen_spicy.jpg | 3 |
根據上面的表,我們可以看到雞蛋有 3 張照片,冰淇淋也有 3 張,而拉麵有 2 張,我們要輸出的是一個 food 和 food_menu 的聚合表,將所有的食物顯示在一起,並結合選單中相應的照片。
如果我們對此進行查詢。
SELECT name, price, options, photo
FROM food, food_menu
WHERE food_id = '1'
結果會是這樣的:
| name | price | options | photo |
|---|---|---|---|
| 1 | Eggs | Scrambled, Sunny Side, Boiled | eggs_sunnyside.jpg |
| 2 | Eggs | Scrambled, Sunny Side, Boiled | eggs_scrambled.jpg |
| 3 | Eggs | Scrambled, Sunny Side, Boiled | eggs_boiled.jpg |
資料是重複的,因為 food_menu 中有多行與 food 相關的資料。在本例中,food_menu 中有 3 張照片是直接與 Eggs 繫結的。
簡單的查詢不可能將 food_menu 中的所有條目連線到一條記錄中,因為它們都被認為是與表 food 相關的獨立實體。
如果你想同時在一行中查詢 food 和 food_menu,那麼這裡有幾個選項。
使用 GROUP BY food 從多個表中 SELECT 的方法
這種方法使用 GROUP BY 將兩張表彙總到一個結果中。但缺點是,你只能得到 food_menu 的第一個例項,因為我們強迫結果是唯一的。
下面是對 GROUP BY food 表的查詢。
SELECT name, price, options, photo
FROM food, food_menu
WHERE food_id = '1'
GROUP BY food_id
它將顯示以下結果。
| name | price | options | photo |
|---|---|---|---|
| 1 | Eggs | Scrambled, Sunny Side, Boiled | eggs_sunnyside.jpg |
現在我們已經滿足了條件,儘管只返回了一張照片,這是查詢發現的第一個 food_menu 例項。
在 MySQL 中使用 JOIN 從多個表中 SELECT
這種方法利用了 SQL 的 JOIN 或 RIGHT JOIN 命令。
我們在指令碼中沒有 2 個 FROM 條件,而是根據它的 food_id 外來鍵來連線 food_menu。我們將 f 作為 food 的別名,將 fm 作為 food_menu 的別名。
SELECT f.name, f.price, f.options, fm.food_menu
FROM food AS f
JOIN food_menu AS fm ON fm.food_id = f.food_id
WHERE food_id = '1'
GROUP BY f.food_id
雖然這個方法與前一個方法不同,但它產生的結果是一樣的。它返回的是 food_menu 的第一個例項,因為 GROUP BY 迫使查詢根據其條件返回唯一的行。
| name | price | options | photo |
|---|---|---|---|
| 1 | Eggs | Scrambled, Sunny Side, Boiled | eggs_sunnyside.jpg |
在 MySQL 中使用 GROUP_CONCAT() 並處理結果
上一個解決方案的變通方法是使用 GROUP_CONCAT() 將 food_menu 的所有結果放在一個單一的字串中,因此可以將他們的所有記錄放在一個行中。
什麼是 GROUP_CONCAT()
GROUP_CONCAT 是一個將多行資料合併到一個欄位的函式。它是一個 GROUP BY 的特殊函式,如果組中至少包含 1 個非空值,則返回一個修改後的字串。否則就返回 NULL。
我們將上面的查詢修改為 GROUP_CONCAT() 照片列,將結果連成一個字串。
SELECT name, price, options, GROUP_CONCAT(photo, ', ')
FROM food, food_menu
WHERE food_id = '1'
GROUP BY food_id
通過這樣做,我們將 food_menu 的照片列連線起來,這樣每條 food 的唯一條目將只產生一條記錄。結果將如下所示。
| name | price | options | photo |
|---|---|---|---|
| 1 | Eggs | Scrambled, Sunny Side, Boiled | eggs_sunnyside.jpg,eggs_scrambled.jpg,eggs_boiled.jpg |
正如你所看到的,它連線了 3 個與 Eggs 相關的 food 表中的 photo 列。
如果我們把 GROUP BY 和 WHERE 條件去掉的話
SELECT name, price, options, GROUP_CONCAT(photo, ', ')
FROM food, food_menu
結果是這樣的
| name | price | options | photo |
|---|---|---|---|
| 1 | Eggs | Scrambled, Sunny Side, Boiled | eggs_sunnyside.jpg,eggs_scrambled.jpg,eggs_boiled.jpg |
| 2 | Ice Cream | Vanilla, Strawberry, Chocolate | icecream_vanilla.jpg,icecream_strawberry.jpg,icecream_chocolate.jpg |
| 3 | Ramen | Regular, Spicy | ramen_regular.jpg,ramen_spicy.jpg |
在使用 GROUP_CONCAT() 時一定要小心,如果你的字串中包含一個逗號,而你的 CONCAT 定界符也是一個逗號,那麼在解析你的列時就會破壞你的資料。
所以在使用這個函式之前,請確保你的定界符對於你要操作的列來說是一個無效的字元。
Skilled in Python, Java, Spring Boot, AngularJS, and Agile Methodologies. Strong engineering professional with a passion for development and always seeking opportunities for personal and career growth. A Technical Writer writing about comprehensive how-to articles, environment set-ups, and technical walkthroughs. Specializes in writing Python, Java, Spring, and SQL articles.
LinkedIn