繁体   English   中英

从两个多对多SQL结构中联接数据

[英]JOIN data from two many-to-many SQL structures

我建立了两个多对多的关系“结构”。 一种是针对电影及其环境:

CREATE TABLE Films (  
id INT NOT NULL AUTO_INCREMENT,  
PRIMARY KEY(id),    
Title VARCHAR(255));

CREATE TABLE Ambiences (  
id INT NOT NULL AUTO_INCREMENT,   
PRIMARY KEY(id),  
ambienceName VARCHAR(255));

CREATE TABLE Films_Ambiences (
film_id INT NOT NULL,  
ambience_id INT NOT NULL,  
PRIMARY KEY (film_id, ambience_id),  
FOREIGN KEY (film_id) REFERENCES Films(id) ON UPDATE CASCADE,  
FOREIGN KEY (ambience_id) REFERENCES Ambiences(id) ON UPDATE CASCADE);

第二个是关于电影及其细节的:

CREATE TABLE Specifics (  
id INT NOT NULL AUTO_INCREMENT,   
PRIMARY KEY(id),  
specificName VARCHAR(255));

CREATE TABLE Films_Specifics (film_id INT NOT NULL,
specific_id INT NOT NULL,
PRIMARY KEY (film_id,specific_id),
FOREIGN KEY (film_id)
REFERENCES Films(id) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (specific_id)
REFERENCES Specifics(id) ON UPDATE CASCADE ON DELETE CASCADE);

我想将所有结果显示在一个表中(按电影标题分组)。 换句话说,我想要:

+-------+--------------+-----------------+
| Title |  Ambiences   |    Specifics    |
+-------+--------------+-----------------+
| film1 | funny, scary | aliens          |
| film2 | sad, scary   | knights, aliens |
| film3 | funny        | knights         |
| .     |              |                 |
| .     |              |                 |
| .     |              |                 |
+-------+--------------+-----------------+

仅在环境中,我使用了一些JOIN和GROUP_CONCAT,如下所示:

SELECT *,GROUP_CONCAT(ambienceName SEPARATOR ', ') AS ambiences
FROM Films AS f 
INNER JOIN Films_Ambiences as fa ON f.id = fa.film_id           
INNER JOIN Ambiences AS a ON a.id = fa.ambience_id
GROUP BY Title

由于环境和细节的原因,我尝试使用两个GROUP_CONCAT by没有解决问题。
如果您愿意,这是一个SQLFiddle

这里的另一个问题是,如果我拥有三个或更多个多对多“结构”,这有意义吗?

UPDATE

我也想展示没有细节的电影。 @Kickstart提出的解决方案似乎并未包含该内容。

换句话说,我想展示一部funny, sad但没有细节的电影。 这是更新的SQLFiddle-您会发现未选择film4。

也许在GROUP_CONCAT中使用DISTINCT

SELECT *,
GROUP_CONCAT(DISTINCT ambienceName SEPARATOR ' ') AS ambiences, 
GROUP_CONCAT(DISTINCT specificName SEPARATOR ' ') AS specifics 
FROM Films AS f 
LEFT OUTER JOIN Films_Ambiences as fa ON f.id = fa.film_id          
LEFT OUTER JOIN Ambiences AS a ON a.id = fa.ambience_id
LEFT OUTER JOIN Films_Specifics as fs ON f.id = fs.film_id          
LEFT OUTER JOIN Specifics AS s ON s.id = fs.specific_id
GROUP BY Title

尝试这个:

select Title,
GROUP_CONCAT(distinct(trim(AMBIENCENAME)),',')as Ambience,
GROUP_CONCAT(distinct(trim(specificName)),',')as Specifics
from Films f join 
Films_Ambiences fa on f.id = fa.film_id join
Ambiences a on a.id=fa.ambience_id join
Films_Specifics fs on fs.film_id = f.id join
Specifics s on s.id = fs.specific_id
group by title;

结果几乎与您说的要保存一些流浪逗号的结果相同。

____________________________________________
|TITLE  |AMBIENCE       |SPECIFICS         |
|-------|---------------|------------------| 
|film1  |sad,           |aliens,           |
|film2  |sad,,happy,    |monsters,         |
|film3  |happy,         |monsters,,aliens, |
--------------------------------------------

编辑:满足以下更新要求的新查询

select Title,
GROUP_CONCAT(distinct(AMBIENCENAME),',')as Ambience,
CASE WHEN specificName is null then 'none' else GROUP_CONCAT(distinct(specificName ),',') END as Specifics
from 
Films f left join
Films_Ambiences fa on f.id = fa.film_id left join
Ambiences a on a.id=fa.ambience_id left join
Films_Specifics fs on fs.film_id = f.id left join
Specifics s on s.id = fs.specific_id
group by title; 

结果:

__________________________________________
|TITLE  |AMBIENCE      |SPECIFICS        |
|----------------------------------------|
|film1  |sad,          |aliens,          |
|film2  |sad,,happy,   |monsters,        |
|film3  |happy,        |aliens,,monsters,|
|film4  |sad,,happy,   |none             |
------------------------------------------

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM