2017-03-07 36 views
0

projects如何使用LEFT JOIN連接多個mySQL表?

+----+--------+------------+ 
| id | title | project_id | 
+----+--------+------------+ 
| 1 | blue |  12345 | 
| 2 | red |  67890 | 
| 3 | yellow |  11111 | 
| 4 | rosa |  22222 | 
+----+--------+------------+ 

connect

+----+------------+-----------+ 
| id | project_id | people_id | 
+----+------------+-----------+ 
| 1 |  12345 |   4 | 
| 2 |  12345 |   3 | 
| 3 |  12345 |   2 | 
| 4 |  22222 |   2 | 
+----+------------+-----------+ 

people

+----+-----------+-----------+----------+ 
| id | firstname | name | position | 
+----+-----------+-----------+----------+ 
| 1 | Diana  | Rose  | singer | 
| 2 | Al  | Capone | singer | 
| 3 | Barbara | Streisand | actor | 
| 4 | Ben  | Harper | musician | 
+----+-----------+-----------+----------+ 

這是我希望的結果:

+----+---------+--------+----------+----------+ 
| id | project | singer | musician | actor | 
+----+---------+--------+----------+----------+ 
| 1 | blue | Capone | Harper | Sreisand | 
| 4 | rosa | Capone |   |   | 
+----+---------+--------+----------+----------+ 

我想達到的效果是這樣的:

<?php 
$pdo = $db->query(' 
    SELECT * 
    FROM projects 
    LEFT JOIN connect ON projects.project_id=connect.project_id 
    LEFT JOIN people ON connect.people_id=people.id;'); 

while ($row = $pdo->fetch(PDO::FETCH_ASSOC)) { 
    echo <td>$row['title']</td>; 
    echo "<td>"; 
    if ($row['position']== "singer"){echo $row['name'];} 
    echo "</td>"; 
    echo "<td>"; 
    if ($row['position']== "musician"){echo $row['name'];} 
    echo "</td>"; 
    echo "<td>"; 
    if ($row['position']== "actor"){echo $row['name'];} 
    echo "</td>"; 
} 
?> 

但我的結果是:

+----+---------+--------+----------+----------+ 
| id | project | singer | musician | actor | 
+----+---------+--------+----------+----------+ 
| 1 | blue | Capone |   |   | 
| 1 | blue |  | Harper |   | 
| 1 | blue |  |   | Sreisand | 
| 4 | rosa | Capone |   |   | 
+----+---------+--------+----------+----------+ 
+1

你說'LEFT JOIN'很多查詢 – RiggsFolly

+0

@RiggsFolly只有兩次 – Jarla

+0

你的意思是你展示的最後一張表是 – RiggsFolly

回答

1

純SQL解決方案:

SELECT res.id, res.project, 
    GROUP_CONCAT(res.singer) as singer, 
    GROUP_CONCAT(res.musician) as musician, 
    GROUP_CONCAT(res.actor) as actor 
FROM (
    SELECT prj.id as id, prj.title as project, 
    IF(ppl.position = 'singer', ppl.name, null) as singer , 
    IF(ppl.position = 'musician', ppl.name, null) as musician, 
    IF(ppl.position = 'actor', ppl.name, null) as actor 
    FROM projects prj 
     LEFT JOIN connect cnt ON prj.project_id=cnt.project_id 
     LEFT JOIN people ppl ON cnt.people_id=ppl.id 
) res 
GROUP BY 1 
HAVING singer IS NOT NULL OR musician IS NOT NULL OR actor IS NOT NULL 
ORDER BY 1 

如果您使用此查詢,PHP的循環可以像

while ($row = $pdo->fetch(PDO::FETCH_ASSOC)) { 
    echo "<td>{$row['project']}</td><td>{$row['singer']}</td><td>{$row['musician']}</td><td>{$row['actor']}</td>"; 
} 

查詢按project.id組合所有人員並連接名稱。子查詢爲每個位置設置名稱。沒有任何人的項目被過濾掉。同樣的結果可以實現使用inner join更高效:

SELECT res.id, res.project, 
    GROUP_CONCAT(res.singer) as singer, 
    GROUP_CONCAT(res.musician) as musician, 
    GROUP_CONCAT(res.actor) as actor 
FROM (
    SELECT prj.id as id, prj.title as project, 
    IF(ppl.position = 'singer', ppl.name, null) as singer , 
    IF(ppl.position = 'musician', ppl.name, null) as musician, 
    IF(ppl.position = 'actor', ppl.name, null) as actor 
    FROM projects prj 
     INNER JOIN connect cnt ON prj.project_id=cnt.project_id 
     INNER JOIN people ppl ON cnt.people_id=ppl.id 
) res 
GROUP BY 1 
ORDER BY 1 

但OP被問及left join明確。