MySQL:能否基于子查询结果计算衍生值?避免重复复杂子查询
复用子查询结果并计算rating的解决方案
当然可以搞定这个需求!不过你直接在SELECT里用total_view和total_comments这两个别名来计算rating会报错哦——因为SQL的执行顺序是先处理WHERE、FROM这些子句,最后才处理SELECT里的字段,同层SELECT里的别名还没被计算出来,数据库没法直接引用它们。
给你两种常用的方法,都能避免重复编写复杂的子查询:
方法一:使用CTE(公共表表达式)推荐
CTE可以先把需要的子查询结果存成一个临时的逻辑表,之后直接用这个表里的字段计算,可读性特别好,适合复杂查询:
WITH product_metrics AS ( SELECT p.id, -- 替换成你的第一个复杂子查询 (SELECT COUNT(*) FROM views v WHERE v.product_id = p.id) AS total_view, -- 替换成你的第二个复杂子查询 (SELECT COUNT(*) FROM comments c WHERE c.product_id = p.id) AS total_comments FROM products p WHERE p.status = "1" ) SELECT id, total_view, total_comments, (total_view * total_comments) AS rating FROM product_metrics ORDER BY rating DESC;
注意:MySQL 8.0及以上、PostgreSQL、SQL Server等主流数据库都支持CTE,如果是老版本MySQL(比如5.x),就用下面的方法。
方法二:使用派生表
把计算好子查询结果的语句作为一个临时派生表,外层查询直接引用它的字段:
SELECT pm.id, pm.total_view, pm.total_comments, (pm.total_view * pm.total_comments) AS rating FROM ( SELECT p.id, -- 替换成你的第一个复杂子查询 (SELECT COUNT(*) FROM views v WHERE v.product_id = p.id) AS total_view, -- 替换成你的第二个复杂子查询 (SELECT COUNT(*) FROM comments c WHERE c.product_id = p.id) AS total_comments FROM products p WHERE p.status = "1" ) AS pm ORDER BY rating DESC;
这种方法兼容性更好,几乎所有数据库都支持。
两种方法的核心思路都是先把复杂子查询的结果计算好,再基于这些结果做运算,完美避免了重复编写子查询的麻烦。
内容的提问来源于stack exchange,提问作者lolalola
相关产品推荐
相关产品推荐

