SQL LEFT JOIN 从第二个表中排除两条记录
Posted
技术标签:
【中文标题】SQL LEFT JOIN 从第二个表中排除两条记录【英文标题】:SQL LEFT JOIN EXCLUDE TWO RECORDS FROM SECOND TABLE 【发布时间】:2020-09-20 15:18:03 【问题描述】:如果状态=是,我正在尝试左连接,并且还想从第二个表中排除记录。但是当我使用 LEFT join 时,它会给出 table1 中的所有记录,而不排除 table2 中状态为“是”的记录。
Table1
--------------------------------
id date
--------------------------------
1 01/09/2020
2 02/09/2020
3 03/09/2020
4 04/09/2020
5 05/09/2020
Table2
--------------------------------
id date status
--------------------------------
1 01/09/2020 Yes
2 02/09/2020 Yes
3 03/09/2020
想要的结果
--------------------------------
id date
--------------------------------
3 03/09/2020
4 04/09/2020
5 05/09/2020
排除 id 1,2 因为 table2 的 status="yes"。
我知道我的 SQL 语法是错误的。请告知正确的语法:
SELECT table1.id,table1.date
FROM table1
LEFT JOIN (select table2.id, table2.date from table2 where status!='Yes') as table2
ON table1.id=table2.id and table1.date = table2.date
【问题讨论】:
请发布您想要的结果。这对正确答案很有用 嗨 Slava,添加了想要的结果。 请在代码问题中给出minimal reproducible example--cut & paste & runnable code,包括最小的代表性示例输入作为代码;期望和实际输出(包括逐字错误消息);标签和版本;明确的规范和解释。给出尽可能少的代码,即您显示的代码可以通过您显示的代码扩展为不正常的代码。 (调试基础。)对于包含 DBMS 和 DDL(包括约束和索引)和输入为格式化为表的代码的 SQL。 How to Ask 暂停总体目标的工作,将代码砍到第一个表达式,没有给出你期望的内容,说出你期望的内容和原因。 【参考方案1】:你需要在WHERE
子句中设置正确的条件:
SELECT t1.*
FROM Table1 t1 LEFT JOIN Table2 t2
ON t2.id = t1.id AND t2.date = t1.date
WHERE COALESCE(t2.status, '') <> 'Yes'
或:
SELECT t1.*
FROM Table1 t1 LEFT JOIN Table2 t2
ON t2.id = t1.id AND t2.date = t1.date
WHERE t2.status IS NULL OR t2.status <> 'Yes'
请参阅demo。 结果:
> id | date
> -: | :---------
> 3 | 03/09/2020
> 4 | 04/09/2020
> 5 | 05/09/2020
【讨论】:
非常感谢。我得到了我想要的结果。我想了解更多关于 WHERE COALESCE(t2.status, '') 'Yes' 的信息。它是如何运作的? COALESCE() 返回其参数的第一个非 null 或 null 如果它们都为 null。所以在这种情况下,如果它不为 null 或 ''(一个空字符串),它会返回 t2.status。【参考方案2】:你可以使用NOT EXISTS
这样的条件来解决这个问题:
SELECT Table1.*
FROM Table1
WHERE NOT EXISTS (
SELECT id FROM Table2 WHERE Table2.id = Table1.id AND Table2.status = 'Yes'
);
【讨论】:
【参考方案3】:如果你想过滤记录,那么使用内连接,而不是外连接:
SELECT t1.id, t1.date
FROM table1 t1 JOIN
table2 t2
ON t1.id = t2.id and t1.date = t2.date
WHERE t2.status <> 'Yes';
编辑:
根据您的评论,我认为NOT EXISTS
是最好的方法:
select t1.*
from table1 t1
where not exists (select 1
from table2 t2
where t1.id = t2.id and t1.date = t2.date and
t2.status = 'Yes'
);
【讨论】:
谢谢戈登。我尝试了这种语法,但不幸的是没有成功。它只给出记录号。来自 table2 的 3,但我想要记录:来自 table1 的 3、4、5。我已在我的帖子中添加了所需的结果,请查看。 @awan 。 . .样本数据有很大帮助。我想你只是想要not exists
。【参考方案4】:
另一种查询如下(因为我真的不明白为什么还需要加入 id):
SELECT `t1`.`id`,`t1`.`date` FROM `Table1` `t1`
LEFT JOIN `Table2` `t2` ON `t1`.`date`=`t2`.`date`
WHERE `t2`.`status` <> 'Yes' OR `t2`.`date` IS NULL;
这是一个相关的SQLFiddle
【讨论】:
【参考方案5】:我会这样写解决方案:
SELECT Table1.id, Table1.date
FROM Table1 LEFT OUTER JOIN Table2
ON Table1.id = Table2.id AND Table2.status = 'Yes'
WHERE Table2.id IS NULL
如您所知,如果没有匹配,左外连接会为右表的行返回 NULL。如果匹配条件包含status='Yes'
,则具有其他状态值的行不匹配。
然后 WHERE 子句将结果限制为 Table1 中没有匹配的行。
【讨论】:
【参考方案6】:试试这个
SELECT t1.*
FROM Table1 t1
LEFT JOIN Table2 t2 ON t2.id = t1.id
WHERE t2.status != 'Yes'
GROUP BY t1.id;
【讨论】:
以上是关于SQL LEFT JOIN 从第二个表中排除两条记录的主要内容,如果未能解决你的问题,请参考以下文章
LEFT JOIN,如果存在第二个表的结果,则添加到 PHP 中的数组
sql语句中join、left join 、right join有啥区别?