SQL Server中连接三张表时如何避免数据冗余?
解决方法:使用UNION ALL拆分销售与采购记录
你的问题根源在于连续两次LEFT JOIN会产生笛卡尔积:当同一个basic_no同时对应多条销售、采购记录时,每条销售记录会和每条采购记录交叉组合,导致冗余数据。
要得到预期的6条结果,需要将销售、采购记录分开查询后合并,具体SQL如下:
SELECT h.id, h.basic_no, s.sell_price, NULL AS buy_price FROM header h LEFT JOIN selling s ON h.basic_no = s.basic_no WHERE s.sell_price IS NOT NULL UNION ALL SELECT h.id, h.basic_no, NULL AS sell_price, b.buy_price FROM header h LEFT JOIN buying b ON h.basic_no = b.basic_no WHERE b.buy_price IS NOT NULL ORDER BY h.basic_no, h.id;
逻辑说明:
- 第一个查询块:关联
header和selling,仅保留存在销售记录的行,采购价格字段填充NULL - 第二个查询块:关联
header和buying,仅保留存在采购记录的行,销售价格字段填充NULL UNION ALL合并两个结果集(不会自动去重,完全匹配你的预期数量)ORDER BY按basic_no和id排序,与预期结果顺序一致
执行结果:
| id | basic_no | sell_price | buy_price |
|---|---|---|---|
| 1a | 1 | 400 | null |
| 1a | 1 | 3 | null |
| 2a | 2 | 10 | null |
| 2a | 2 | null | 15 |
| 3a | 3 | 75 | null |
| 3a | 3 | null | 100 |
另外注意你原SQL中的笔误:on a.basic_no = s.basic_no里的a应为h(header的别名),否则会触发语法错误。
内容的提问来源于stack exchange,提问作者cindyy
相关产品推荐
相关产品推荐

