2013-07-12 97 views
0

我建立了两个多对多关系“结构”。一个是用于薄膜和它们的氛围:从两个多对多SQL结构中加入数据

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的由没试过不行。
这里是一个SQLFiddle如果你喜欢。

这里还有一个问题,如果我有三个或更多的多对多'结构'而且它有意义吗?

UPDATE

我也想显示它们没有什么具体的薄膜。 @Kickstart提出的解决方案似乎没有包括这一点。

换句话说,我想显示一个电影funny, sad,但没有具体细节。 这里是更新的SQLFiddle - 你会发现电影4没有被选中。

回答

1

使用DISTINCT在GROUP_CONCAT也许

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 
+0

似乎不符合我给SQLFiddle工作。 – Sharkz

+2

'Films_Specifics'的连接条件应该是'ON f.id = fs.film_id'(不是'ON f.id = fa.film_id')。 –

+0

@Kickstart,哦,等一下,看起来像是有效的。我在小提琴中犯了一个小错误。谢谢! – Sharkz

0

试试这个:

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, | 
-------------------------------------------- 

编辑:新的查询,以满足UPDATE需要量低于

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    | 
------------------------------------------ 
+0

谢谢,但阿伦得到了我正在寻找的anwser;) – Sharkz

+0

没问题!感谢您向我展示SQLFiddle它的一个漂亮的工具! – Legion

+0

我修复了我的查询,以便它能够满足您发布结果示例的新要求! – Legion