一个业务逻辑引发的对多表连接的思考

 

 

StringBuilder sb = new StringBuilder();
sb.Append("insert into lx_ZBBaoYangLog(MatId,MatName,State,CreateTime) ");
sb.Append("select a.ID,a.EqName,0,GETDATE() from lx_Equipment as a left join lx_ZBBaoYangLog as b on a.id = b.MatId where(b.MatId is null or b.State <> 0) and NextBaoYang <= '" + DateTime.Now + "' ");
//在满足现在时间大于保养时间的情况下,有两种情况会被插入到保养表里.1:该装备在保养表里的state=0的,2:该装备在保养表里没有的
DbHelper.ExecuteSqlCommand(sb.ToString());

 

批量插入语句:insert into 保养表(value..)select (value...) from 装备表

实现上面业务逻辑主要难点是在查的部分,实现---(//在满足现在时间大于保养时间的情况下,有两种情况会被插入到保养表里.1:该装备在保养表里的state=0的,2:该装备在保养表里没有的)

实现这个需求可以有两种查的思路

1:不使用多表连接,差不多是内连接的思路(我也不知道这种说法对不对)

大概是这样子 select(value)from 装备表 where id not in(select  matid from 保养表 where 没有保养完成的)

2.多表连接

select  value from 装备表  left join 保养表 on 装备表.id=保养表.Matid  where (b.MatId is null or b.State<>0) and NextBaoYang<=getdate()

 多表连接的方式是装备表左连接保养表,也就是说最终会显示装备表里符合的所有数据,包括了保养表里没有的数据,这些没有的数据就满足了《保养表里不存在该装备》这个逻辑,所以写成b.Matld is null是正确的,也是一开始我不理解的。

 

我一开始的写法我展示一下

 

这种写法有两个错误。

1:查不到数据:因为前面那个多表连接的装备表和后面那个装备表不是同一个(这个有点复杂),所以我要把b.state 放到内连接的那个()里面作为条件而不是放在外面作为多表连接的条件

 2:sql滥用,既用了多表连接又用了内链接,两个没必要放在一起,前面用了多表连接就应该在多表连接产生的那个结果里去做文章,而不该再去搞个内连接,这样效率低下,影响sql性能。

 

多表连接产生的是类似视图一样的虚拟表,只是用来查看的,不能用来进行其他操作,在linq时多表连接也是产生了一个新的对象,最后取得字段也应该从新对象取而不是旧的对象。

posted @ 2019-03-08 14:52  那一片蓝海  阅读(197)  评论(0编辑  收藏  举报