求sql,用not exist双重否定的方式
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求sql,用not exist双重否定的方式相关的知识,希望对你有一定的参考价值。
s(s#,sname)
sc(s3,c#,cname)
查询所学课程包含学生S3所学课程的学生学号。
你说的双重否定是指not exist 否定一次,然后查询语句里否定一次么?你看这样符合你的要求么?
select * from s where not EXISTS (select * from sc where s3<>学生S3的学号) 参考技术A SELECT DISTINCT S#FROM SC AS X
WHERE NOT EXISTS
(SELECT *
FROM SC AS Y
WHERE Y.S# = 'S3'
AND NOT EXISTS
(SELECT *
FROM SC AS Z
WHERE Z.S# = X.S#
AND Z.C# = Y.C#))追问
麻烦解释下,特别是WHERE Z.S# = X.S#
AND Z.C# = Y.C#,谢谢
这个很难说明白,
自己理解吧
WHERE Z.S#=X.S#
AND Z.S#=X.S#不行么
那当然不行了,
你写了2个条件完全一样。
她需要 用 y 和z 进行判断
不好意思 是WHERE Z.S#=X.S#
AND Z.S#=Y.S#不行么
不行,关于课程 c# ,你没有任何判断。!
不行,关于课程 c# ,你没有任何判断。!
本回答被提问者采纳小酌重构系列[21]——避免双重否定
避免双重否定
在自然语言中,双重否定表示肯定。但是在程序中,双重否定会降低代码的可读性,使程序不易理解,容易产生错觉。
人通常是用“正向思维”去理解一件事情的,使用双重否定的判断,需要开发者以“逆向思维”的方式去理解它的含义。
另外,在写程序时,"!"符号很容易被疏忽和遗漏,一不小心则会编写出错误的代码,从而产生bug。
所以,在程序中,我们应当尽量避免使用双重否定。
优惠券是否未被使用?
还是以在线商城给用户发放优惠券为例,由于优惠券的初始状态是未被使用的,所以设计人员将优惠券的使用状态设计为IsUnused。
/// <summary> /// 优惠券 /// </summary> public class Coupon { /// <summary> /// 是否未被使用 /// </summary> public bool IsUnused { get; set; } }
这样设计会带来两个小问题
- IsUnused表示“优惠券是否未被使用”,这句话本身是比较拗口的,开发人员需要“逆向思维”去理解它的含义。
- 在写程序时,如果要判断“优惠券已经被使用”,则需要编写比较绕弯的程序
// 如果优惠券已经被使用了 if (!coupon.IsUnused) { // 业务逻辑 }
这段代码如果没有第1行的注释,是比较难于理解的,也许你是用以下方式理解的。
理解这段代码看起来颇为费劲,我们应该换种方式来理解它。
因此,将属性设计为IsUsed更为合适。
/// <summary> /// 优惠券 /// </summary> public class Coupon { /// <summary> /// 是否被使用 /// </summary> public bool IsUsed { get; set; } }
编写的判断语句,可读性良好,也易于理解。
// 如果优惠券已经被使用了 if (coupon.IsUsed) { // 业务逻辑 }
PS:设计程序毕竟不是唱Rap,你没必要把自己饶进去了,又把别人也绕进去,大家都能轻易读懂的代码才可能是好的代码。
示例
重构前
这段代码使用!customer.IsNotFlagged
判断“客户账户被标记”,如果没有注释,这个判断就比较难理解。
public class Order { public void Checkout(IEnumerable<Product> products, Customer customer) { // 如果客户账户被标记了 if (!customer.IsNotFlagged) { // 记录错误并返回 return; } // 正常的订单处理流程 } } public class Customer { public decimal Balance { get; private set; } public bool IsNotFlagged { get { return Balance < 30m; } } }
程序本意是为了表达一个肯定的语义——“如果客户账户是被标记的”,既然如此,我们何不直接用肯定的语义来表示它呢?
重构后
重构后,代码读起来就更加直观了,也很容易被理解。
public class Order { public void Checkout(IEnumerable<Product> products, Customer customer) { // 如果客户账户被标记了 if (customer.IsFlagged) { // 记录错误并返回 return; } // 正常的订单处理流程 } } public class Customer { public decimal Balance { get; private set; } public bool IsFlagged { get { return Balance >= 30m; } } }
小结
在设计bool类型的属性时,不仅要表达清楚它所表示的业务含义,还应当考虑编写代码时的复杂性,尽量避免使用双重否定。
以上是关于求sql,用not exist双重否定的方式的主要内容,如果未能解决你的问题,请参考以下文章
为啥 SQL 中无法避免双重嵌套的 NOT EXISTS 语句
T-SQL,求IF EXISTS和IF NOT EXISTS的实际使用示例