mysql - 我如何使用连接来组合这两个查询?

标签 mysql join

我有两个表:文章和修改。我希望用户能够轻松地将他们的文章恢复到原始状态,如果他们意识到他们不应该修改它的话。我不想使用额外的查询来查找文章最新修改的 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>)

http://sqlfiddle.com/#!2/14051/2

关于mysql - 我如何使用连接来组合这两个查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26477126/

相关文章:

php - SQL Select 使用同一表中的不同参数

mysql - 每个连接的计数 - 优化

php - 我在 php 中的 INSERT INTO SELECT FROM 语句正确吗?

mysql - LEFT JOIN 导致右表中的一列出现错误的空记录

php - 如何创建sql文件?

MySQL 通过返回不需要的结果使用 COUNT、LEFT JOIN 和 GROUP

SQL Server 在填充了值的列上加入

mysql 选择加入第二行

mysql - SQL 查询两个不同查询中的行值

PHP 7 RC3 : How to install missing MySQL PDO