DISTINCT 去重的是整行而非单列,JOIN 一对多时因关联字段差异导致"看似重复实则不同";应优先用 EXISTS/IN、GROUP BY 或 ROW_NUMBER() 精准控制去重逻辑。为什么 DISTINCT 加了还是有重复?不是 DISTINCT 不管用,而是它去重的是整行结果------只要任意一列值不同,就算"不重复"。多表 JOIN 后,一对多关系(比如一个订单对应多个商品)天然会把主表记录"撑开",此时哪怕你只选主表字段,数据库仍按连接后的中间结果去重,ORDER_ID 看似一样,但因关联的 ITEM_ID、QUANTITY 等字段参与了 JOIN,整行实际不同。实操建议:先确认重复根源:用 SELECT * 查看原始 JOIN 结果,观察哪几列在变如果只需要主表数据,优先考虑 EXISTS 或 IN 替代 JOIN,避免物理拼接DISTINCT 必须紧贴 SELECT,不能写成 SELECT DISTINCT a.* FROM ...(MySQL 8.0+ 支持,但多数旧版本报错)用 GROUP BY 替代 DISTINCT 更可控GROUP BY 明确指定按哪些列聚合,比 DISTINCT 更易预测行为,也方便后续加聚合函数(如统计子项数量)。但它要求所有 SELECT 中的非分组字段必须用聚合函数包裹,否则报错(SQL 标准严格模式下)。常见错误现象:SELECT order_id, customer_name, COUNT(*) FROM orders o JOIN items i ON o.id = i.order_id GROUP BY order_id ------ customer_name 未出现在 GROUP BY 且没聚合,MySQL 5.7+ 默认拒绝执行。实操建议:只选主表关键字段时,GROUP BY 列和 SELECT 列保持一致,例如 SELECT o.id, o.status FROM orders o JOIN ... GROUP BY o.id, o.status需要附带子表信息(如最新一条日志),改用窗口函数 ROW_NUMBER() OVER (PARTITION BY order_id ORDER BY created_at DESC) 过滤注意 GROUP BY 性能:字段越多、数据量越大,临时表和排序开销越高LEFT JOIN + IS NULL 检查缺失关联时别误伤主表想查"没关联到子表的主表记录",常写 LEFT JOIN ... WHERE sub.id IS NULL。但如果子表有多条匹配记录,LEFT JOIN 仍会产生多行,再用 WHERE 过滤时逻辑没问题,但容易忽略:若子表本就允许空值或存在重复键,IS NULL 可能匹配出意料之外的行。使用场景:排查订单无支付记录、用户无头像等"缺失"类问题。 RedClaw 百度推出的手机端万能AI Agent助手
相关推荐
HaiXCoder2 小时前
python从入门到精通-第8章: 类型系统 — Python的类型注解革命一战成名9962 小时前
把“看菜谱”变成“跟着做”:基于 Rokid 灵珠平台打造智能眼镜应用《厨房教练》小熊Coding2 小时前
Windows 上安装 mysqlclient 时遇到了编译错误,核心原因是缺少 Microsoft Visual C++ 14.0 或更高版本 的编译环境。好家伙VCC2 小时前
# BERT在中文文本分类中的实战优化:从基础模型到高效部署BERT(Biu0107475462 小时前
JavaScript 递归调用栈深度解析与层级遍历陷阱详解本地化文档2 小时前
requests-docs-l10nMetaphor6922 小时前
使用 Python 将 PowerPoint 转换为 PDFherinspace2 小时前
管家婆实用帖-如何使用ping命令检测网络环境