多表UNION查询DISTINCT作用及唯一Item数量统计咨询
解答你的SQL查询疑问
先结合你的场景梳理下:你有sales_order、invoice、purchase_order三张业务表,都通过item_id关联到item中心表,想要找出指定日期范围内有活动的唯一item_id,同时想统计这些item的总数。咱们一步步解决你的两个疑问:
疑问1:DISTINCT的作用范围与UNION后的重复问题
直接给你明确结论:
- 子查询里的
DISTINCT是单独作用于每个子查询的结果集,比如SELECT DISTINCT item_id FROM sales_order...会先把销售订单表中该日期范围内重复的item_id去重,再交给UNION处理。 UNION关键字本身会对所有子查询合并后的整体结果集做去重操作,所以哪怕你子查询里不用DISTINCT,最终的联合结果也不会有重复的item_id。
换句话说,你当前语句里子查询的DISTINCT其实是多余的——因为UNION已经帮你完成了全局去重。如果换成UNION ALL(不会自动去重),那子查询的DISTINCT才有用,用来先去掉单表内的重复值。
所以你的联合查询最终返回的是无重复的item_id列表,完全不用担心重复值问题。
疑问2:统计唯一item总数的正确写法
你尝试的统计语句是不可行的,因为COUNT()函数不能直接接收一个多结果的子查询作为参数。正确的做法是把联合查询作为派生表,再统计这个派生表的行数:
SELECT COUNT(*) FROM ( SELECT item_id FROM sales_order WHERE entry_date BETWEEN ? AND ? UNION SELECT item_id FROM invoice WHERE entry_date BETWEEN ? AND ? UNION SELECT item_id FROM purchase_order WHERE entry_date BETWEEN ? AND ? ) AS active_items;
逻辑很清晰:内层通过UNION得到所有无重复的活跃item_id,外层用COUNT(*)统计这个结果集的行数,就是你要的唯一item总数。
额外补充:如果你的业务表中item_id不会在单表内重复(比如sales_order里同一个item_id不会对应多条同日期范围的记录),内层UNION里的子查询完全可以去掉DISTINCT,查询效率还会更高。
内容的提问来源于stack exchange,提问作者ryvantage
相关产品推荐
相关产品推荐

