WHERE!=在SQL中没有按预期工作

时间:2017-06-04 02:12:40

标签: sql oracle

我目前正在运行此代码:

select distinct day 
from v_nem_rm16, dbp_holiday 
where v_nem_rm16.day != dbp_holiday.holiday_date;

为什么我仍然会在v_nem_rm16.day等于dbp_holidays.holiday_day的情况下获得结果?我想过滤掉v_nem_rm16.day中日期等于dbp_holidays.holiday_day中日期的所有行。

2 个答案:

答案 0 :(得分:1)

检索所请求数据的查询已由其他帖子提供。 但你也问过:

  

为什么我仍然得到v_nem_rm16.day等于dbp_holidays.holiday_day的结果?

假设您的dbp_holidays表包含至少两个不同的日期:

table: dbp_holidays

holiday_day
----------
2015-05-01
2015-07-31
2015-12-25

v_nem_rm16包含的日期可能与dbp_holidays的日期重合,也可能不重合,例如

table: v_nem_rm16

day
----------
2015-02-17
2015-12-25

交叉连接

select
    v_nem_rm16.day
    dbp_holidays.holiday_day
from    
    v_nem_rm16,
    dbp_holidays

检索以下元组

day         holiday_day
----------  ----------
2015-02-17  2015-05-01
2015-02-17  2015-07-31
2015-02-17  2015-12-25
2015-12-25  2015-05-01
2015-12-25  2015-07-31
2015-12-25  2015-12-25

所以v_nem_rm16表中的每一行都出现n次,其中n是dbp_holidays的行数。

添加where子句最多可以删除每个v_nem_rm16.day值中的一个,并且每个v_nem_rm16.day个日期至少有n-1行。

所以

select
    v_nem_rm16.day
    dbp_holidays.holiday_day
from    
    v_nem_rm16,
    dbp_holidays
where   
    v_nem_rm16.day != dbp_holidays.holiday_day

检索

day         holiday_day
----------  ----------
2015-02-17  2015-05-01
2015-02-17  2015-07-31
2015-02-17  2015-12-25
2015-12-25  2015-05-01
2015-12-25  2015-07-31

将选择列表缩小为

select
    v_nem_rm16.day
from    
    v_nem_rm16,
    dbp_holidays
where   
    v_nem_rm16.day != dbp_holidays.holiday_day

给出

day
----------
2015-02-17
2015-02-17
2015-02-17
2015-12-25
2015-12-25

应用不同运算符

之后
select
    distinct v_nem_rm16.day
from    
    v_nem_rm16,
    dbp_holidays
where   
    v_nem_rm16.day != dbp_holidays.holiday_day

我们得到了

day
----------
2015-02-17
2015-12-25

选择返回v_nem_rm16表的所有天。

答案 1 :(得分:0)

为什么不使用not exists

select r.day 
from v_nem_rm16 r
where not exists (select 1
                  from dbp_holiday h
                  where r.day = h.holiday_date
                 );

您可以使用JOIN,特别是LEFT JOIN

执行您想要的操作
select r.day 
from v_nem_rm16 r left join
     dbp_holiday h
     on r.day = h.holiday_date
where h.holiday_date is null;

这只是强调了为什么你不应该在from子句中使用逗号并始终使用显式join语法。