在 MariaDB 中显示 NULL 值(LEFT JOIN 给出错误值)

Posted

技术标签:

【中文标题】在 MariaDB 中显示 NULL 值(LEFT JOIN 给出错误值)【英文标题】:Display NULL values in MariaDB (LEFT JOIN gives wrong values) 【发布时间】:2020-08-27 16:46:58 【问题描述】:

因此,我正在尝试查询选择 SUM 的所有分钟都来自“科幻”电影中演员的角色。 当我执行 INNER JOIN 时,我得到了正确的值,但它不显示 NULL 值,然后当我执行 LEFT JOIN 时,我得到完全不同的值,这些值远高于预期。 这是查询选择

SELECT a.actor_id, a.first_name, a.last_name, SUM(allfilms.length)
    AS 'total_combined_film_length'
FROM actor a
LEFT JOIN film_actor film_a ON a.actor_id = film_a.actor_id
LEFT JOIN film allfilms ON film_a.film_id = allfilms.film_id
LEFT JOIN film_category film_c ON allfilms.film_id = film_c.film_id
INNER JOIN category c on film_c.category_id = c.category_id && c.name='Sci-Fi'
GROUP BY a.actor_id
ORDER BY (a.actor_id) DESC;

结果给了我:

+----------+-------------+--------------+----------------------------+
| actor_id | first_name  | last_name    | total_combined_film_length |
+----------+-------------+--------------+----------------------------+
|      200 | THORA       | TEMPLE       |                        287 |
|      198 | MARY        | KEITEL       |                        314 |
|      197 | REESE       | WEST         |                        190 |
|      196 | BELA        | WALKEN       |                         59 |
|      195 | JAYNE       | SILVERSTONE  |                        263 |
|      193 | BURT        | TEMPLE       |                        113 |

事实上,我也想要以下条目:

|      199 | JOHN        | SMITH       |                           0 |
|      194 | RODGER      | FED         |                           0 |

这是我在最终 JOIN 上执行 LEFT JOIN 时的样子,而不是 INNER JOIN,即:

LEFT JOIN category c on film_c.category_id = c.category_id && c.name='Sci-Fi'
+----------+-------------+--------------+----------------------------+
| actor_id | first_name  | last_name    | total_combined_film_length |
+----------+-------------+--------------+----------------------------+
|      200 | THORA       | TEMPLE       |                       2568 |
|      199 | JULIA       | FAWCETT      |                       1555 |
|      198 | MARY        | KEITEL       |                       4962 |
|      197 | REESE       | WEST         |                       3897 |
|      196 | BELA        | WALKEN       |                       3198 |
|      195 | JAYNE       | SILVERSTONE  |                       3217 |
|      194 | MERYL       | ALLEN        |                       2729 |

谢谢,有什么帮助。真的只是好奇为什么这些值都搞砸了!

【问题讨论】:

【参考方案1】:

尝试以下操作,将c.name='Sci-Fi'where 放在一起。

SELECT a.actor_id, a.first_name, a.last_name, SUM(allfilms.length)
    AS 'total_combined_film_length'
FROM actor a
LEFT JOIN film_actor film_a ON a.actor_id = film_a.actor_id
LEFT JOIN film allfilms ON film_a.film_id = allfilms.film_id
LEFT JOIN film_category film_c ON allfilms.film_id = film_c.film_id
LEFT JOIN category c on film_c.category_id = c.category_id 
WHERE c.name='Sci-Fi'
GROUP BY a.actor_id
ORDER BY (a.actor_id) DESC;

【讨论】:

仍然没有给出空值 @MatthewJacobsen 只是尝试调试您的查询,对您拥有的所有JOIN 逐一进行,看看哪个JOIN 导致了问题,我相信您会找到根本原因。如果不查看测试数据,我们可能无法提供太多帮助。【参考方案2】:

有几种方法可以解决像您这样的问题。这可能是最简单的:

SELECT  a.actor_id, a.first_name, a.last_name,
        COALESCE(
          ( SELECT SUM(f.length)
            FROM  film_actor AS fa    ON a.actor_id = fa.actor_id
            JOIN  film allfilms AS f  ON fa.film_id = f.film_id
            JOIN  film_category AS fc ON f.film_id = fc.film_id
            JOIN  category c          ON fc.category_id = c.category_id
            WHERE  c.name='Sci-Fi'
          )
        ) AS 'total_combined_film_length'
    FROM  actor a
    ORDER BY  a.actor_id DESC;

注意事项:

你想要全部actors,对吗? COALESCE 是将NULL 转换为0 的一种方法。 多对多映射表效率提示:http://mysql.rjweb.org/doc.php/index_cookbook_mysql#many_to_many_mapping_table 请注意,GROUP BY 在此公式中是不必要的。 (这会加快查询速度。) 如果您想要COUNT(*) AS number_of_films,我会推荐一个不同的公式,可能涉及一个“派生”表。

【讨论】:

以上是关于在 MariaDB 中显示 NULL 值(LEFT JOIN 给出错误值)的主要内容,如果未能解决你的问题,请参考以下文章

传递给 WebService 的 HTML 值显示为 NULL

MYSQL Left Join 如何选择 NULL 值?

MariaDB / pymysql:数据在列中显示为十六进制值(0x5761746572 而不是“水”)

MySQL/MariaDB 中的存储过程不允许使用 NULL 参数

LINQ LEFT JOIN 不适用于 NULL 值

从 LEFT JOIN 设置 NULL 列的默认值并使用 WHERE 过滤