2015-10-13 67 views
2

我有以下表格:在3个表中选择属于哪个属性的mysql数据?

+-------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+---------+----------------+ 
| c_id  | bigint(20) | NO | PRI | NULL | auto_increment | 
| c_name  | varchar(255) | NO |  | NULL |    | 
+-------------+--------------+------+-----+---------+----------------+ 

文章

+-------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+---------+----------------+ 
| a_id  | bigint(20) | NO | PRI | NULL | auto_increment | 
| a_name  | varchar(255) | NO |  | NULL |    | 
+-------------+--------------+------+-----+---------+----------------+ 

Course_Articles

+-------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+---------+----------------+ 
| ca_id  | bigint(20) | NO | PRI | NULL | auto_increment | 
| a_id  | bigint(20) | NO |  | NULL |    | 
| c_id  | bigint(20) | NO |  | NULL |    | 
| t_id  | bigint(20) | NO |  | NULL |    | 
| sort_order | int(11)  | NO |  | NULL |    | 
+-------------+--------------+------+-----+---------+----------------+ 

期限(或学期)

+-------------+--------------+------+-----+---------+----------------+ 
| Field  | Type   | Null | Key | Default | Extra   | 
+-------------+--------------+------+-----+---------+----------------+ 
| t_id  | bigint(20) | NO | PRI | NULL | auto_increment | 
| t_name  | varchar(255) | NO |  | NULL |    | 
| c_id  | bigint(20) | NO |  | NULL |    | 
| sort_order | int(11)  | NO |  | NULL |    | 
+-------------+--------------+------+-----+---------+----------------+ 

我需要从这些表显示数据如下:

课程名称:现代天然气开采

文章:

  • 介绍
  • 概述气体提取技术

  • 期限1:常规技术

    • 煤矿甲烷
    • 另一种常规技术
  • 另一篇文章不在术语

  • 另外一个

  • 期限2:非常规技术

    • 煤炭地下气化
    • 煤层气
    • 水力压裂
  • 结论

我知道这个数据将受益也许嵌套/树。但这是我必须合作的。正如你所看到的文章可以属于一个术语或者是独立的。

对于如何高效地查询以上输出按照示例,我有点难住。

<?php 
// UPDATED with UNION as suggested 
try { 
$stmt = $dbh->prepare(
    "SELECT ca . * , a.a_name, t.t_name 
FROM Course_Article AS ca 
LEFT JOIN Article AS a ON a.a_id = ca.ca_id 
LEFT OUTER JOIN Term AS t ON t.t_id = ca.t_id 
WHERE ca.c_id = '2' 
UNION SELECT te.t_name, te.t_id, te.c_id 
FROM Term AS te 
WHERE te.t_id = '2'"); 

$last_term_id = -1; 

$stmt->execute(); 
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) { 
    if ($last_term_id != $row['t_id']) { 
    echo "<b>" . $row['t_name'] . "</b><br />"; 
    $last_term_id = $row['t_id']; 
    } 
    echo $row['a_name'] . "<br />"; 
    } 
} catch(PDOException $e) { 
    echo 'Error : '. $e->getMessage(); 
    exit(); 
    } 
?> 

谢谢

+0

不要混合连接样式。事实上,如果你从来不使用逗号连接,那么你不会犯太多错误。 – Strawberry

+0

'高效地查询' - 以及把你的sql查询有相当基本的级别错误,也许你应该尝试学习一些关于sql基础知识之前寻求其他人的帮助(=解决方案)。 – ejuhjav

+0

我有一个脑屁。我想你没有得到那些。 ;) –

回答

0

因此,这里是一个知道如何与工会做到这一点:第一部分得到下他们所有的条款(也是空的)和文章,和第二部分得到所有的其他文章属于课程,但不属于任何学期。希望我没有在这里包含太多的逻辑/打字错误。

select t.t_name, ca.*, a.a_name 
from Term t 
left outer join Course_Article ca ON ca.t_id = t.t_id 
left outer join Article a ON a.a_id = ca.a_id 
where t.c_id = '2' 

UNION 

select null as t_name, ca.*, a.a_name 
from Course_Articles ca 
left outer join Article a ON a.a_id = ca.a_id 
where ca.c_id = '2' and ca.t_id is null 

此外,如果您需要订购的结果的位(说不上如果排序顺序是当然的文章和词之间通用的),你可以扩展这个有点(添加你需要的最后不管列结果导入主要选择):

select t_name, a_name, sort_column 
FROM 
(
    select t.t_name, ca.*, a.a_name, t.sort_order as sort_column 
    from Term t 
    left outer join Course_Article ca ON ca.t_id = t.t_id 
    left outer join Article a ON a.a_id = ca.a_id 
    where t.c_id = '2' 

    UNION 

    select null as t_name, ca.*, a.a_name, ca.sort_order as sort_column 
    from Course_Articles ca 
    left outer join Article a ON a.a_id = ca.a_id 
    where ca.c_id = '2' and ca.t_id is null 
) dt 
order by sort_column ASC 
+0

Thx ejuhjav,第一人似乎几乎这样做,尽管由于某种原因某个术语有2篇文章返回4次(2 x与不正确的c_id和2与正确的c_id和相关文章)。排序很重要,所以我会尝试。尽管这是最接近的! –

+1

我稍微更新了答案(从工会的第二部分删除了一个不必要的连接):您是否已经检查过哪些部分的联合会导致太多/不正确的行? – ejuhjav

+0

现在我收到一个错误,因为删除左外连接使我们失去了术语名称。 –