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