MySQL子查询获取派生值:列值在另一列中出现次数查询的错误排查
排查MySQL子查询错误并修正
嘿,咱们先揪出你写的查询语句里的问题:
你原来的语句是:
SELECT A, B, (SELECT COUNT(A) FROM T WHERE B = A) AS C FROM T
这里的核心问题是列名的作用域冲突——子查询里的A和B都是指向子查询内部的表T,而不是外层查询的T表中的列。也就是说,子查询实际上在找“子查询表中B列等于自身A列”的行数,这和你想要的“外层行的A值在整个B列中出现的次数”完全不是一回事,所以结果才全是0。
修正方案:给表加别名区分内外层
我们可以给外层表和子查询里的表分别起不同的别名,明确指定子查询里要匹配的是外层表的A值。修正后的语句如下:
SELECT t1.A, t1.B, (SELECT COUNT(t2.B) FROM T t2 WHERE t2.B = t1.A) AS C FROM T t1;
举个例子验证
假设你的表T数据是这样的:
| A | B |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 2 |
执行修正后的语句,得到的结果会是:
| A | B | C |
|---|---|---|
| 1 | 1 | 2 |
| 2 | 1 | 1 |
| 3 | 2 | 0 |
额外优化小提示
如果你的表数据量比较大,子查询可能会有点慢,你也可以用JOIN结合分组的方式来实现,效率可能更高:
SELECT t1.A, t1.B, COALESCE(t2.count_b, 0) AS C FROM T t1 LEFT JOIN ( SELECT B, COUNT(*) AS count_b FROM T GROUP BY B ) t2 ON t2.B = t1.A;
这个写法先把B列的每个值的出现次数统计好,再和原表关联,避免了每行都执行一次子查询,性能会更优~
内容的提问来源于stack exchange,提问作者Sachu
相关产品推荐
相关产品推荐

