[英]Selecting Categories from a joined table and concatenating to form listing results
我對在MySQL中使用GROUP_CONCAT感到有些困惑。
為了說明,我正在一個清單目錄上工作,例如類似於Yelp。 用戶過濾不同的條件,並返回不同的位置。
例如,如果用戶希望查看所有已被分類(或標記為)“餐廳”或“休息室”的地點,則他們將僅看到那些地點,而且還應為它們顯示任何其他標記的類別。
為此,我在數據庫中構建了一些表。 ,涉及到這個問題的主要表是表places
和categories
和place_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.name
為NULL
,因此將其過濾掉。
編輯:
如果只想在結果中(與其他人一起使用)休息室類別,則只需添加一個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.