簡體   English   中英

Mysql JOIN用IN和RIGHT表的多個結果

[英]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.

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