[英]Mysql JOIN with IN and multiple results of RIGHT table
LEFT表(簡化)是:
id
name (ex:Bob)
tags (ex:1,4,6)
右表是:
id
tag (ex:Sailing)
我想得到這樣的LEFT表的結果:
row 1:
name: Bob
tags: Sailing,Snowboard,...
我得到的最接近的是:
SELECT `name`, GROUP_CONCAT(`right`.`tag`) AS tags
FROM (`left`)
LEFT OUTER JOIN `right` ON `right`.`id` IN(left.tags)
ORDER BY `name` asc
但由於GROUP_CONCAT(),這只給了我一行。 沒有它,它給了我所有的結果,但只有逗號分隔列表中的第一個標記。 我知道我很接近,但我已經失去了太多時間。 任何幫助贊賞。
我知道我可以創建第三個表left_right,它包含行(id,left_id,right_id)以使其工作,但我想避免這種情況。
首先bažmegakapa所說的是正確的,還有更多。 如果我理解你所描述的設置,你已經浪費了相當大的空間(和表演)。
你可以這樣做:
CREATE TABLE pleft ( id integer, name varchar(20), tags integer );
CREATE TABLE pright ( id integer, tag varchar(20));
INSERT INTO pleft VALUES ( 1, 'Bob', 1 ), ( 9, 'Bob', 4 ), ( 15, 'Bob', 6 );
INSERT INTO pleft VALUES ( 2, 'Ann', 1 ), ( 3, 'Joe', 4 ), ( 4, 'Joe', 6 );
INSERT INTO pright VALUES ( 1, 'Sailing' ), ( 4, 'Snowboarding' ), ( 6, 'Skiing' );
SELECT pleft.name, GROUP_CONCAT(pright.tag)
FROM pleft JOIN pright ON ( pleft.tags = pright.id )
GROUP BY pleft.name ORDER BY pleft.name;
+------+-----------------------------+
| name | GROUP_CONCAT(pright.tag) |
+------+-----------------------------+
| Ann | Sailing |
| Bob | Sailing,Skiing,Snowboarding |
| Joe | Snowboarding,Skiing |
+------+-----------------------------+
...但請注意名稱如何在pleft
表的每一行中不必要地重復。 理想情況下,您可以使用一個表來模擬人:(id = 1,name =“Bob”),一個表模擬標簽(id = 6,value =“Skiing”)和一個包含其關系的表。 這將確保,例如,鮑勃決定通過“羅伯特”,你不必去除整個標簽表,但只有涉及鮑勃的一行。
UPDATE
所以tags
是一個包含“1,4,6”的varchar字段。 同樣的邏輯適用,但現在我們必須拆分字段再次重新啟動它。 你不能使用“1 in tags”之類的東西,因為“11”會返回true(“1”包含在“11”中)。 (這是稱為“Jaywalking”的SQL反模式:請參閱https://groups.google.com/forum/?fromgroups=#!topic/django-users/5j4AmQE6nTk )
SELECT pleft.name, GROUP_CONCAT(pright.tag)
FROM pleft JOIN pright
ON ( CONCAT(',',pleft.tags,',') LIKE CONCAT('%,',pright.id,',%' ))
GROUP BY pleft.name ORDER BY pleft.name;
另一種方法是使用存儲過程:請參閱http://www.marcogoncalves.com/2011/03/mysql-split-column-string-into-rows/ 。
CREATE TABLE pleft ( id integer, name varchar(20), tags varchar(20) );
INSERT INTO pleft VALUES ( 1, 'Bob', '1,4,6' ), ( 2, 'Jill', '4,1' );
SELECT pleft.name, GROUP_CONCAT(pright.tag)
FROM pleft JOIN pright
ON ( CONCAT(',',pleft.tags,',') LIKE CONCAT('%,',pright.id,',%' ))
GROUP BY pleft.name ORDER BY pleft.name;
+------+-----------------------------+
| name | GROUP_CONCAT(pright.tag) |
+------+-----------------------------+
| Bob | Sailing,Snowboarding,Skiing |
| Jill | Sailing,Snowboarding |
+------+-----------------------------+
嘗試添加GROUP BY名稱字段,您應該能夠選擇包含其標簽的所有名稱的列表。
SELECT `name`, GROUP_CONCAT(`right`.`tag`) AS tags
FROM (`left`)
LEFT OUTER JOIN `right` ON `right`.`id` IN(left.tags)
GROUP BY `name`
ORDER BY `name` ASC;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.