我有两个表:文章和修改。我希望用户能够轻松地将他们的文章恢复到原始状态,如果他们意识到他们不应该修改它的话。我不想使用额外的查询来查找文章最新修改的 id,而是使用连接。所以我想从文章表中获取信息,然后将修改表连接到它以返回关联的行。这就是我现在拥有的:
<?php
$query = "
SELECT
article_id, title, content
FROM articles
WHERE article_id = ".$article_id."
LIMIT 1";
$query_article = $this->db->query($query);
$article = $query_article->row_array();
$query_mod = "
SELECT
modification_id, article_id, title, content, date
FROM modifications
WHERE article_id = ".$article_id."
ORDER BY modification_id DESC
LIMIT 1";
$query_mod = $this->db->query($query);
if($query_mod->num_rows() > 0){
$mod = $query_mod->row_array();
$article_title = $mod['title'];
$article_content = $mod['content'];
} else {
$article_title = $article['title'];
$article_content = $article['content'];
}
如何使用连接将这两个查询合并为一个?
SELECT
a.title, a.content, a.article_id
m.modification_id AS mod_id, m.title AS mod_title, m.content AS mod_content
FROM articles AS a
LEFT JOIN modifications AS m ON (...)
WHERE a.article_id = 1
LIMIT 1
最佳答案
除了空的 ON
子句外,您对查询的基本尝试几乎是正确的,它只需要确定两个表上的 article_id
之间的相等性。使用 LEFT JOIN
是正确的,因为无论 modifications
是否匹配,您都需要返回文章。
SELECT
a.title, a.content, a.article_id,
m.modification_id AS mod_id, m.title AS mod_title, m.content AS mod_content
FROM
articles AS a
LEFT JOIN modifications AS m ON a.article_id = m.article_id
WHERE a.article_id = 1
ORDER BY mod_id DESC LIMIT 1
但是,您的 PHP 逻辑显示您有条件地使用 modifications
表中的 title,content
(如果存在)。为此,您可以使用 COALESCE()
直接在 SQL 中返回第一个非空参数,因此如果 LEFT JOIN
没有匹配项,将使用 article
。
SELECT
-- COALESCE to prefer the modifications value if non-null
COALESCE(m.title,a.title) AS title,
COALESCE(m.content, a.content) AS content,
a.article_id,
m.modification_id AS mod_id
FROM
articles AS a
LEFT JOIN modifications AS m ON a.article_id = m.article_id
WHERE a.article_id = 1
ORDER BY mod_id DESC LIMIT 1
这是一个演示:http://sqlfiddle.com/#!2/1085c/1
因为您只是试图返回一个 article_id
的详细信息,所以不需要子查询。如果您想返回多个 article_id
的最新信息,这会变得有点复杂,需要使用 MAX()
聚合的子查询连接。
SELECT
COALESCE(m.title,a.title) AS title,
COALESCE(m.content, a.content) AS content,
a.article_id,
m.modification_id AS mod_id
FROM
articles AS a
-- Join articles against a subquery to get the most recent mod_id only
LEFT JOIN (
SELECT article_id, MAX(modification_id) AS mod_id
FROM modifications
GROUP BY article_id
) mm ON mm.article_id = a.article_id
-- and then join that mod_id against the rest of the modifications table
LEFT JOIN modifications m ON mm.mod_id = m.modification_id
WHERE article_id IN (<multiple criteria for article_id>)
关于mysql - 我如何使用连接来组合这两个查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26477126/