如何用两个不同的表完成JOIN?

时间:2014-01-09 19:49:39

标签: mysql sql

我正在尝试将两个查询合并为一个,以便我可以仅使用从两个表中检索到的数据。

查询

有两个表:文章 article_tags

public function latestArticles()
{
    $sth = $this->db->prepare("SELECT * FROM articles       
                               WHERE article_uid = article_uid
                               ORDER BY article_uid DESC");
    $sth->execute();
    $row = $sth->fetchAll();
    return $row;
}

public function articleTags()
{
    $sth = $this->db->prepare("SELECT a.*, b.*
                               FROM articles a, article_tags b
                               WHERE b.article_id = a.article_uid
                               ");
    $sth->execute();
    $row = $sth->fetch();
    return $row;
}

我无法将这两个函数合并为一个foreach,因此我建议使用JOIN来提高效率和速度。我为不包括我所尝试的内容而道歉,过去三个小时他们都以失败告终。

2 个答案:

答案 0 :(得分:1)

SELECT 
    table1.col1
,   table2.col2
FROM
    table1
INNER JOIN table2 ON table1.id = table2.table1id;

答案 1 :(得分:1)

public function latestArticlesWithTags()
{
    $sth = $this->db->prepare("SELECT a.*, b.* FROM articles a
                               LEFT JOIN article_tags b on a.article_uid = b.article_id
                               ORDER BY article_uid DESC ");
    $sth->execute();
    $row = $sth->fetchAll();
    return $row;
}

但是这不会起作用,除非标签表与文章表是1比1,我真的怀疑。如果一篇文章的标签很多,那么你就可以获得它可以匹配的第一个标签行。您可以像这样反转查询:

$sth = $this->db->prepare("SELECT a.*, b.* FROM article_tags b
                           LEFT JOIN articles a on a.article_uid = b.article_id
                           ORDER BY article_uid DESC");

但是你会得到一堆重复的文章以及它的匹配标签:

| Aritcle   | Tag   |
| Article 1 | Tag 1 |
| Article 1 | Tag 2 |
| Article 1 | Tag 3 |

更好的解决方案可能不是返回第一个查询中的所有文章,然后分页结果。或者可能将标签缓存为文章旁边的标准化数据,以便显示它们只需要去激励而不是另一个查询。

此外,虽然这些查询效率不高(从不使用*,但始终显式设置要返回的列,以便只加载所需的数据)除非正在运行,否则您可能没有从中获得性能损失非常多。