SELECT
p.project_code AS 项目编码,
p.project_name AS 项目名称,
count( e.id ) AS 建筑数量,
count( d.id ) AS 设备数量
FROM
`emp_project` p
LEFT JOIN `architecture` e ON p.id = e.`project_id`
AND e.`is_active` = 1
AND e.`level` = 30
AND e.`source_type` = 'Z'
LEFT JOIN `project_device` d ON p.id = d.project_id
AND d.is_active = 1
AND d.device_type IN ( 1, 2, 3, 4 )
WHERE
p.`is_active` = 1
AND p.`source_type` = 'Z'
GROUP BY
p.id
SELECT
p.project_code AS 项目编码,
p.project_name AS 项目名称,
en.encount AS 建筑数量,
de.decount AS 设备数量
FROM
`emp_project` p
LEFT JOIN ( SELECT `project_id`, count(*) AS encount FROM `architecture` WHERE `level` = 30 AND `is_active` = 1
AND `source_type` = 'Z' GROUP BY `project_id` ) en ON p.id = en.`project_id`
LEFT JOIN (
SELECT
`project_id`,
count(*) AS decount
FROM
`project_device`
WHERE
`is_active` = 1
AND `device_type` IN ( 1, 2, 3, 4 )
GROUP BY
`project_id`
) de ON p.id = de.project_id
WHERE
p.`is_active` = 1
AND p.`source_type` = 'Z'
这两段 sql 在同一个库里执行,结果天差地别,但是从连接和分组以及查询条件来看,感觉不出来有什么差异,大佬们能不能一眼丁真帮看下原因
1
hxpmc 288 天前
第二个慢?
|
2
bingfengCoder OP @hxpmc 不是快慢的问题,现在不考虑性能,它们查询结果完全不一样,就是 count 值差别很大,但是从直觉上去读这两个 sql ,总感觉又没毛病
|
3
Xinu 288 天前
没去问问 gpt 吗 现在 sql 问题一律先问 gpt
|
4
bingfengCoder OP @Xinu 问过了,结果就是人工智障,它告诉我这是两个相似的 sql ,结果也应该相似。。。。但是实际执行结果 count 相差很大
|
5
gerryzhu0033 288 天前 1
left join 和 right join 后面不要用 where ,用了 where 就变普通 join 了
|
6
inkmulberry 288 天前
感觉上应该是第一个 count 更大
|
7
houfeibin 288 天前 1
第二种结果是对的
|
8
ZZ74 288 天前 1
注意 left join
第一句 p 中 project id 就算 e ,d 中没有对应的 也会被 count 第二句 就不会有问题 而且现在 sql 都那么宽泛了吗? 第一句 sql 你 count 的话 不应该是 group by project_code 和 name 为啥要是 id... 怎么说呢 你这两个统计值应该做成两个 sql 用 inner join.... |
9
jorinabill111 288 天前
逆天丁真
|
10
8355 288 天前
sql1 的 join 2 次纬度差异 导致的 count 数量不对吧
从来没有想过这种魔法的操作 你的主 sql 本身与 e/d 表条件没有任何关联就应该单独直接 sql count |
12
bingfengCoder OP @inkmulberry 是的,第一个 count 会比较大,但是这种大是不准确的,找不到原因
|
13
5sheep 288 天前
笛卡尔乘积造成的
|
14
bingfengCoder OP @ZZ74 试过 group by project_code,name 和 group by id 结果是一样的,count 都不准确。。。。
|
15
ZZ74 288 天前
|
16
ivvei 288 天前 via Android
语法都不对,这是 mysql 吧?
|
17
liprais 288 天前
建议你再学学
真是一眼就能看出区别 |
18
mytoroto 288 天前
同意楼上,再学学,你这是基本功有问题啊
|
20
bingfengCoder OP @mytoroto 能细说下吗
|
21
bingfengCoder OP @liprais 能展开说下吗,想知道问题出在哪里
|
22
sorcerer 288 天前 via Android
最简单的情况
表 1 一条记录 表二满足 join 条件的有两条记录 也就是 project id 一样的有两条 表三 project id 一样的有 3 条 这样通过方法 1 关连后 最终表里有 6 条记录 ,count 表二和表三的 proj id 都等于 6 方法二最终结果只有一条,凑 count 表二 表三的结果分边为 2 和 3 |
23
cccmm 288 天前
architecture 表或 project_device 表的 project_id 有重复?
|
24
kkwa56188 288 天前
|
25
xuanbg 287 天前
@bingfengCoder 第一种的 count 其实是右表的行数,第二种 count 的是右表 id 的个数。
在 count 函数里面加 distinct ,写成以下的代码,结果就一致了: SELECT p.project_code AS 项目编码, p.project_name AS 项目名称, count(distinct e.id ) AS 建筑数量, count(distinct d.id ) AS 设备数量 FROM `emp_project` p LEFT JOIN `architecture` e ON p.id = e.`project_id` AND e.`is_active` = 1 AND e.`level` = 30 AND e.`source_type` = 'Z' LEFT JOIN `project_device` d ON p.id = d.project_id AND d.is_active = 1 AND d.device_type IN ( 1, 2, 3, 4 ) WHERE p.`is_active` = 1 AND p.`source_type` = 'Z' GROUP BY p.id |
26
bingfengCoder OP @xuanbg 试了下,结果一致了,感谢大佬
|
27
bingfengCoder OP @kkwa56188 25 楼 大佬给出了 详细的写法,group by 可以跑起来的,结果一致了
|
29
bingfengCoder OP @M48A1 现在第一个 group by 不仅不会报错,还能得到正确的结果了 详见 25 楼 XD
|
30
bingfengCoder OP 不知道为什么大家会把第一种 group by 主表字段 当成邪教用法,但是通过有效的 left join 可以很好的避免子查询产生的次数,我不太喜欢写很多个子查询然后 一个个 join ,更倾向直接 join 然后一把 group by 梭,感觉要来的更加方便
|
31
M48A1 287 天前 via iPhone
@bingfengCoder 什么版本呀,我被淘汰了
server sql 必须加满 group by. |
32
bingfengCoder OP @M48A1 用的 mysql 5.7 ,mysql 8 加了 ONLY_FULL_GROUP_BY 模式 也是需要加满的
|
33
Richared 287 天前
没仔细看,但是我感觉第一个种写法 count 的值有重复的。去重下?
|