今天下午,开发人员问了个问题。
问题:T1(F11、F12)、T2(F21、F22)、T3(F31、F32)三表关联,想查出T1的F11等于T2的F21或者T2的F31的T1所有记录,即(F11=F21 or F11=F31),然后他这么写select T1.* from T1,T2,T3 where T1.F11=T2.F21 or T1.F11=T3.F31,可一直查不出记录。
分析:从逻辑上说,这样写sql没错。查看数据,T1 -1条、T2-3条、T3 -0,按照理解应该出来1条记录,
去掉where条件,查询还是没有记录,所以知道三表全联接有问题。查笛卡尔积资料,∀A: A ∩ {} = {} 对任意集合 A, 空集和 A 的笛卡尔积为空集。
总结:空集 的笛卡尔积永远为空集。虽然很简单的问题,还是疑惑了半天,看来做技术的大学数学还是必须学好的。
重点说下,上面写的sql有严重问题,没有关联字段的表连接即交叉联接,将返回若有数据表的笛卡尔积,如果数据量大,则会导致查询效率直线下降,所以一般写sql不要做交叉联接。
推荐写法:
select T1.* from T1 where exists (select 1 from T2 where T1.T11=T2.F21) or exists (select 1 from T3 where T1.T11=T3.F31)