咨询:基于共同字段关联三张表以获取全表数据的SQL语句是否正确?
你的SQL语句存在几个问题,无法满足“所有表的数据均出现在查询结果中”的需求
先直接给结论:你写的SQL语句不正确,主要问题集中在连接方式、语法错误和关联条件的完整性上,下面逐一拆解:
1. 隐式内连接会过滤掉不匹配的行
你用逗号分隔三张表的写法属于隐式内连接,这种方式只会返回满足所有WHERE条件的行——也就是说,如果table1里有一条folio在table2或table3中找不到匹配项,这条数据会被直接过滤掉,完全不符合“所有表的数据都要出现”的要求。
2. =any(table3.folio1, table3.folio2) 语法错误
ANY运算符的正确用法是配合子查询,比如 = ANY(SELECT folio1 FROM table3),而不是直接跟两个字段。如果要匹配table3的folio1或folio2,应该用逻辑OR来实现:
table1.folio = table3.folio1 OR table1.folio = table3.folio2
3. 缺少iss_code字段的关联逻辑
你的table1和table2都有共同字段iss_code,table3也有iss_code1和iss_code2,但原SQL完全没处理这个字段的关联。这会导致即使folio匹配,iss_code不匹配的行也会被错误地关联在一起,产生大量无效的笛卡尔积结果。
满足需求的正确SQL写法
要让三张表的所有数据都出现在结果中,你需要使用全外连接(FULL OUTER JOIN),它会保留所有表中不满足关联条件的行(用NULL填充缺失的字段)。下面是示例代码:
SELECT * FROM table1 -- 先关联table1和table2,用两个共同字段确保匹配准确 FULL OUTER JOIN table2 ON table1.folio = table2.folio AND table1.iss_code = table2.iss_code -- 再关联table3,匹配任意一个folio和对应的iss_code FULL OUTER JOIN table3 ON (table1.folio = table3.folio1 OR table2.folio = table3.folio1 OR table1.folio = table3.folio2 OR table2.folio = table3.folio2) AND (table1.iss_code = table3.iss_code1 OR table2.iss_code = table3.iss_code1 OR table1.iss_code = table3.iss_code2 OR table2.iss_code = table3.iss_code2);
注意:如果你的数据库不支持FULL OUTER JOIN(比如MySQL)
可以用左外连接+右外连接+UNION来模拟全外连接的效果:
-- 左连接保留table1的所有数据 SELECT * FROM table1 LEFT JOIN table2 ON table1.folio = table2.folio AND table1.iss_code = table2.iss_code LEFT JOIN table3 ON (table1.folio = table3.folio1 OR table2.folio = table3.folio1 OR table1.folio = table3.folio2 OR table2.folio = table3.folio2) AND (table1.iss_code = table3.iss_code1 OR table2.iss_code = table3.iss_code1 OR table1.iss_code = table3.iss_code2 OR table2.iss_code = table3.iss_code2) UNION -- 右连接保留table2和table3中未被左连接覆盖的数据 SELECT * FROM table1 RIGHT JOIN table2 ON table1.folio = table2.folio AND table1.iss_code = table2.iss_code RIGHT JOIN table3 ON (table1.folio = table3.folio1 OR table2.folio = table3.folio1 OR table1.folio = table3.folio2 OR table2.folio = table3.folio2) AND (table1.iss_code = table3.iss_code1 OR table2.iss_code = table3.iss_code1 OR table1.iss_code = table3.iss_code2 OR table2.iss_code = table3.iss_code2);
内容的提问来源于stack exchange,提问作者Amol Bakane
相关产品推荐
相关产品推荐

