Mysql 选择conditon=met和condition=not met的位置,但存在condition=met的相关行(JOIN?UNION?子查询?)

Mysql 选择conditon=met和condition=not met的位置,但存在condition=met的相关行(JOIN?UNION?子查询?),mysql,sql,Mysql,Sql,我需要得到一个结果集,其中的行满足某些条件,但也包括不满足主要条件的行,但链接到满足这些条件的行。我知道这听起来可能很复杂,也不清楚,所以我将这个探索转化为一个简单的例子 +--------------------------------+ | people | +--------------------------------+ | ID | Name | IsRich | ParentID | +-----------------------

我需要得到一个结果集,其中的行满足某些条件,但也包括不满足主要条件的行,但链接到满足这些条件的行。我知道这听起来可能很复杂,也不清楚,所以我将这个探索转化为一个简单的例子

+--------------------------------+
| people                         |
+--------------------------------+
| ID  | Name | IsRich | ParentID |
+--------------------------------+
| 100 | John | 1      | NULL     |
| 101 | Tom  | 0      | NULL     |
| 102 | Kate | 0      | 101      |
| 103 | Bob  | 0      | 100      |
| 104 | Mike | 1      | 105      |
| 105 | Bill | 0      | NULL     |
+--------------------------------+
在本例中,我想选择所有富人和不富有但有一个有钱孩子的人:

可以使用什么SQL来获取此结果集?

子查询、并集、联接、某种形式的WHERE条件,还有什么


另外,如果可以的话,请帮我重新表述问题标题。

做选择应该会让你觉得
在哪里
。这是一种典型的表达方式:

select t.*
from t
where t.isRich = 1 or
      t.Id in (select t2.ParentId from t t2 where t2.isRich = 1)

做选择应该让你认为
在哪里
。这是一种典型的表达方式:

select t.*
from t
where t.isRich = 1 or
      t.Id in (select t2.ParentId from t t2 where t2.isRich = 1)

戈登·林诺夫(Gordon Linoff)提到的子选择非常有效。但是,如果您想使用联接(例如,从子级提取额外数据),这里有另一个可能的解决方案

SELECT
    *
FROM
    -- look at all of the rows of people
    people parent
     -- tack on the child of each row
    LEFT JOIN people child ON child.ParentID = parent.ID
WHERE
    -- if either the child or the parent are rich, return the row
    (child.isRich = 1 || parent.isRich = 1)

戈登·林诺夫(Gordon Linoff)提到的子选择非常有效。但是,如果您想使用联接(例如,从子级提取额外数据),这里有另一个可能的解决方案

SELECT
    *
FROM
    -- look at all of the rows of people
    people parent
     -- tack on the child of each row
    LEFT JOIN people child ON child.ParentID = parent.ID
WHERE
    -- if either the child or the parent are rich, return the row
    (child.isRich = 1 || parent.isRich = 1)

这在工会中也是可能的

# SELECT all rich people (parent)
SELECT 
   people.id
 , people.Name
 , people.isRich
FROM 
 people
WHERE
 people.isRich = 1 

UNION ALL

# SELECT people (parent) with an rich child.
SELECT
   parent.ID
 , parent.Name
 , parent.isRich
FROM 
 people parent
INNER JOIN 
 people child 
ON
 parent.id = child.parentID
WHERE 
 child.isRich = 1
结果

    id  Name    isRich  
------  ------  --------
   100  John           1
   104  Mike           1
   105  Bill           0

请参见演示

这也可以通过一个接头实现

# SELECT all rich people (parent)
SELECT 
   people.id
 , people.Name
 , people.isRich
FROM 
 people
WHERE
 people.isRich = 1 

UNION ALL

# SELECT people (parent) with an rich child.
SELECT
   parent.ID
 , parent.Name
 , parent.isRich
FROM 
 people parent
INNER JOIN 
 people child 
ON
 parent.id = child.parentID
WHERE 
 child.isRich = 1
结果

    id  Name    isRich  
------  ------  --------
   100  John           1
   104  Mike           1
   105  Bill           0

请参见演示

sql小提琴:似乎有效,但我不确定我们是否想要有钱人或有有钱孩子的人,或者不有钱但有有钱孩子的人。@DanFarrell。我认为很明显,OP的意图是:“选择所有富有的人和不富有的人,但有一个富有的孩子”。sql小提琴:似乎有效,但我不确定我们想要的是富有的人还是有一个富有的孩子,或者是不富有的人有一个富有的孩子。@DanFarrell。我想很明显,OP的意图是
:“选择所有富有的人和不富有的人,但有一个富有的孩子”。这可能会创建多行多个孩子只是一个警告,在MySQL中,子行可能会变得棘手。MSSQL提供了常用的表表达式,允许您使用类似于表的结构(本质上是一个链表)并对富子代、孙子代、大孙子代等进行查询。如果您需要MySQL的这一功能,最好执行检入代码。@Papazzi,没错。OP没有指定行是否需要区分,或者是否应该显示每个组合。如果一个父级不需要多行,可以向查询中添加一个DISTINCT。(例如,选择不同的父项。*来自…)谢谢大家。在我的情况下,行的唯一性是由以后的代码体系结构保证的,但就性能而言,最好不要有重复的行。这可能会创建多行多个子行只是一个警告,子行在MySQL中可能会变得棘手。MSSQL提供了常用的表表达式,允许您使用类似于表的结构(本质上是一个链表)并对富子代、孙子代、大孙子代等进行查询。如果您需要MySQL的这一功能,最好执行检入代码。@Papazzi,没错。OP没有指定行是否需要区分,或者是否应该显示每个组合。如果一个父级不需要多行,可以向查询中添加一个DISTINCT。(例如,选择不同的父项。*来自…)谢谢大家。在我的情况下,行的唯一性是由以后的代码体系结构保证的,但从性能上看,最好不要有重复的行。@GurV虽然理论上是可能的,但我的特定数据集不会包含孙子关系。但如果是这样的话,我希望包括每一位父母和祖父母。目前,我不需要让SQL变得比需要的更复杂。顺便说一句,我不明白你的第二个评论。@GurV虽然理论上是可能的,但我的特定数据集不会包含孙子关系。但如果是这样的话,我希望包括每一位父母和祖父母。目前,我不需要让SQL变得比需要的更复杂。顺便说一句,我不明白你的第二句话。