如何从左表返回行,其中右表的条件在没有子查询的所有行上为真

Posted

技术标签:

【中文标题】如何从左表返回行,其中右表的条件在没有子查询的所有行上为真【英文标题】:How to return rows from left table where condition on right table true on all row without sub query 【发布时间】:2021-09-09 09:56:52 【问题描述】:

我有 2 个包含此示例数据的表。

父母

id title
1 A
2 B
3 C

儿童

id p_id number
1 1 1
2 1 2
3 1 3
4 2 4
5 2 5
6 2 6
7 3 2
8 3 7
9 3 8
10 3 9

我想从父母那里得到行,加入孩子和数字 > 3。

但我只想接收所有孩子的条件都正确的父母,即使一个孩子的条件不正确,也不应该返回父母

我想不用子查询

SELECT * FROM `parent` 
LEFT JOIN `childs` on `childs`.`p_id` = `parent`.`id` 
WHERE `childs`.`number` > '3'

我只想得到符合这种条件的父母 B。

谢谢。

【问题讨论】:

【参考方案1】:

也许这样的东西可以工作

SELECT *
FROM parent p, child c2
WHERE EXISTS ( SELECT * 
          FROM child c1 
          WHERE p.id = c1.p_id AND c1.number >3)  AND  p.id = c2.p_id AND c2.number <=3

【讨论】:

OP 希望父母的行与孩子一起加入。不仅仅是父母。【参考方案2】:

试试这个:

SELECT p.id, p.title, GROUP_CONCAT(number ORDER BY number) val
  FROM Parent p JOIN Childs c ON p.id=c.p_id
  GROUP BY p.id, p.title
  HAVING SUBSTRING_INDEX(val,',',1) > 3;

这是fiddle demo

【讨论】:

【参考方案3】:

我想从父母那里得到行,加入孩子和数字 > 3。

但我只想接收所有孩子的条件都正确的父母,即使一个孩子的条件不正确,也不应该返回父母

我会推荐:

SELECT p.id, p.title
FROM Parent p JOIN
     Childs c
     ON p.id = c.p_id
GROUP BY p.id, p.title
HAVING MIN(number) > 3;

根本没有理由将字符串用于您想做的事情。它只是混淆了逻辑。

更有效的方法是使用NOT EXISTS

select p.*
from p
where not exists (select 1
                  from childs c
                  where p.id = c.p_id and c.number <= 3
                 );

【讨论】:

以上是关于如何从左表返回行,其中右表的条件在没有子查询的所有行上为真的主要内容,如果未能解决你的问题,请参考以下文章

左外连接和右外连接的区别

从左表返回所有行,从右表返回不同的匹配行

SQL表连接查询(inner join(join)full joinleft joinright join)

MySQL——联表查询

MySQL--7种join连接

7-10外连接查询