簡體   English   中英

從連接的表中選擇類別並進行鏈接以形成列表結果

[英]Selecting Categories from a joined table and concatenating to form listing results

我對在MySQL中使用GROUP_CONCAT感到有些困惑。

為了說明,我正在一個清單目錄上工作,例如類似於Yelp。 用戶過濾不同的條件,並返回不同的位置。

例如,如果用戶希望查看所有已被分類(或標記為)“餐廳”或“休息室”的地點,則他們將僅看到那些地點,而且還應為它們顯示任何其他標記的類別。

為此,我在數據庫中構建了一些表。 ,涉及到這個問題的主要表是表placescategoriesplace_category_rel這樣:

位置表:

+----+------------------+
| id | name             | 
+----+------------------+
| 1  | Johns Restaurant |
+----+------------------+
| 2  | Jims Place       |
+----+------------------+
| 3  | Cafe Luna        |
+----+------------------+

place_category_rel

+----------+-------------+
| place_id | category_id |
+----------+-------------+
| 1        | 1           |
+----------+-------------+
| 1        | 2           |
+----------+-------------+

類別

+----+------------+
| id | name       |
+----+------------+
| 1  | Lounge     |
+----+------------+
| 2  | Restaurant |
+----+------------+
| 3  | Night Club |
+----+------------+

要獲得所有位置,我使用以下查詢:

SELECT p.id,
       p.name,
       group_concat(DISTINCT cat.name separator ',') as categories
FROM places p
LEFT JOIN places_categories_rel rel ON p.id=rel.place_id
LEFT JOIN categories cat ON cat.id=rel.category_id
GROUP BY p.id

這使我得到這個結果集:

+----+------------------+--------------------+
| id | name             | categories         |
+----+------------------+--------------------+
| 1  | Johns Restaurant | Lounge,Restaurant  |
+----+------------------+--------------------+
| 2  | Jims Place       | Null               |
+----+------------------+--------------------+
| 3  | Cafe Luna        | Null               |
+----+------------------+--------------------+

上面的作品很棒。 但是,當我添加WHERE子句以篩選歸類為“休息室”的地方時,我失去了另一個類別:

SELECT p.id,
       p.name,
       group_concat(DISTINCT cat.name separator ',') as categories
FROM places p
LEFT JOIN places_categories_rel rel ON p.id=rel.place_id
LEFT JOIN categories cat ON cat.id=rel.category_id
WHERE cat.name = 'Lounge' 
GROUP BY p.id

結果:

+----+------------------+------------+
| id | name             | categories |
+----+------------------+------------+
| 1  | Johns Restaurant | Lounge     |
+----+------------------+------------+

我想要的是這個結果集:

+----+------------------+--------------------+
| id | name             | categories         |
+----+------------------+--------------------+
| 1  | Johns Restaurant | Lounge, Restaurant |
+----+------------------+--------------------+

有人可以指出我正確的方向嗎? 謝謝。

使用LEFT JOIN ,除第一個表外的所有條件都應在ON子句中:

SELECT p.id,
       p.name,
       group_concat(DISTINCT cat.name separator ',') as categories
FROM places p LEFT JOIN
     places_categories_rel rel
     ON p.id = rel.place_id LEFT JOIN
     categories cat
     ON cat.id = rel.category_id AND cat.name = 'Lounge' 
GROUP BY p.id;

請記住: LEFT JOIN返回第一個表中的所有行,無論ON子句返回true,false還是NULL 如果ON條件不成立,則第二個(及后續)表中的所有列均為NULL

當您在WHERE子句中測試cat.name = 'Lounge'時,對於不匹配的行, cat.nameNULL ,因此將其過濾掉。

編輯:

如果只想在結果中(與其他人一起使用)休息室類別,則只需添加一個having子句:

SELECT p.id,
       p.name,
       group_concat(DISTINCT cat.name separator ',') as categories
FROM places p LEFT JOIN
     places_categories_rel rel
     ON p.id = rel.place_id LEFT JOIN
     categories cat
     ON cat.id = rel.category_id
GROUP BY p.id
HAVING SUM(cat.name = 'Lounge') > 0;

我認為這是最簡單的方法。

如果我的理解正確,則您嘗試獲取給定位置的所有類別(如果它們具有特定類別)。 假設這樣,則exists一種選擇:

SELECT p.id,
       p.name,
       group_concat(DISTINCT cat.name separator ',') as categories
FROM places p
   LEFT JOIN places_categories_rel rel ON p.id=rel.place_id
   LEFT JOIN categories cat ON cat.id=rel.category_id
WHERE EXISTS (
   SELECT 1
   FROM places_categories_rel pcr 
       JOIN categories c ON c.id=pcr.category_id
   WHERE name = 'Lounge'  AND p.id=pcr.place_id
)
GROUP BY p.id

在這種情況下,也不確定是否需要outer joins -可能與inner joins相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM