【笛卡尔积】sql中交叉联接的误解

今天下午,开发人员问了个问题。

问题: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)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值