【问题标题】:MySQL “NOT IN” query 3 tablesMySQL “NOT IN” 查询 3 个表
【发布时间】:2023-03-21 14:25:01
【问题描述】:

我有 3 个表课程、成绩和评估。我想比较两张表的等级和评价。如果表grade中的数据在表评估中不存在,则数据会出现(输出)

"   select Grade.ID_Courses,Course.ID_Courses,Grade.NAME, 
    Course.NAME, Grade.ID_Courses,
    Evaluation.NAME,
    Evaluation.Year,    
    Grade.Year
    from Grade, Course, Evaluation
    WHERE 
    Grade.ID_Courses=Course.ID_Courses AND 
    Grade.NAME=JOHN and 
    Grade.Year=1 and 
    Evaluation.NAME=GRADE.NAME and
    Grade.ID_Courses NOT IN (SELECT ID_Courses FROM Evaluation where NAME=JOHN and Year=1 )
    GROUP BY Grade.ID_Courses"

问题是当名字 john 不在表评估中时,没有输出。

【问题讨论】:

  • 避免not in.try not exists或left join patterns
  • 这是一个很好的查询!
  • 就此而言,尝试显式连接模式!

标签: php mysql sql


【解决方案1】:

像瘟疫一样避免NOT IN

SELECT ID_Courses FROM Evaluation where `NAME`='JOHN' and Year=1

可以包含 NULL。相反,使用 NOT EXISTS 或左连接

使用显式连接,而不是使用 WHERE 子句的 1980 年风格连接

为了说明 NOT IN 的痛苦:

SQL NOT IN () 危险

create table mStatus
(   id int auto_increment primary key,
    status varchar(10) not null
);
insert mStatus (status) values ('single'),('married'),('divorced'),('widow');

create table people
(   id int auto_increment primary key,
    fullName varchar(100) not null,
    status varchar(10)  null
);

块 1:

truncate table people;
insert people (fullName,`status`) values ('John Henry','single');
select * from mstatus where `status` not in (select status from people);

** 3 行,如预期 **

块2:

truncate table people;
insert people (fullName,`status`) values ('John Henry','single'),('Kim Billings',null);
select * from mstatus where status not in (select status from people);

没有行,对吧?

显然这是“不正确的”。它源于 SQL 使用三值逻辑, 由 NULL 的存在驱动,NULL 是一个指示缺失(或 UNKNOWN)信息的非值。 用 NOT IN,Chunk2 翻译成这样:

status NOT IN ('married', 'divorced', 'widowed', NULL)

这相当于:

NOT(status='single' OR status='married' OR status='widowed' OR status=NULL)

表达式“status=NULL”的计算结果为 UNKNOWN,根据三值逻辑规则, NOT UNKNOWN 也计算为 UNKNOWN。结果,所有行都被过滤掉,查询返回一个空集。

可能的解决方案包括:

select s.status
from mstatus s
left join people p
on p.status=s.status
where p.status is null

或使用not exists

【讨论】:

  • 这是一个极端的“陷阱”!尽管精通null 的危险,但在这里我会无意识地假设,尽管使用= 比较已知值,但将使用is null 语义比较null。当然不是,= null 会生成未知结果,这会使其余部分无效,整个事情都崩溃了。 (我似乎记得过去对此感到困惑,并且可能被 SO 答案所保存,尽管可能不是这个,因为我没有使用 PHP。:D)
【解决方案2】:

尝试使用连接来解决这个问题

select g.*, e.*,c.* from
      grade g inner join evaluation e on
      g.ID_COURSES <> e.ID_COURSES and g.year <> e.year
      inner join COURSE c on c.ID_COURSES = g.ID_COURSES
      ;

【讨论】:

    猜你喜欢
    • 2014-08-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-18
    • 1970-01-01
    • 2015-09-28
    • 2013-07-18
    • 1970-01-01
    相关资源
    最近更新 更多