如何从组中选择所有行,直到出现值

时间:2017-10-18 19:59:05

标签: mysql sql

我正在尝试从同一Group中提取所有行,直到我达到断点值B。以下示例数据是有序虚拟表:

+----+--------+------------+
| ID | Group  | Breakpoint |
+----+--------+------------+
| 1  | 1      | A          |
| 2  | 1      | A          |
| 3  | 1      | B          |
| 4  | 1      | A          |
| 5  | 2      | A          |
| 6  | 2      | A          |
| 7  | 2      | A          |
| 8  | 3      | A          |
| 9  | 3      | B          |
+----+--------+------------+

这将是我的结果。

+----+--------+------------+
| ID | Group  | Breakpoint |
+----+--------+------------+
| 1  | 1      | A          |
| 2  | 1      | A          |
| 5  | 2      | A          |
| 6  | 2      | A          |
| 7  | 2      | A          |
| 8  | 3      | A          |
+----+--------+------------+

请注意,如果组中有AB个断点值,我希望按此顺序排列第一个A值。如果A中的某个组只有group 2个值,我希望该组中包含所有项目。

5 个答案:

答案 0 :(得分:1)

从上面的示例中,您并未真正对结果进行分组。你只需要显示断点是A的记录:

Select * From Table
Where Breakpint ='A'

答案 1 :(得分:1)

这是一个不使用子查询或GROUP BY逻辑的简单解决方案。

SELECT t1.ID, t1.Group, t1.Breakpoint
FROM MyTable AS t1
LEFT OUTER JOIN MyTable AS t2
  ON t1.ID >= t2.ID AND t1.`Group` = t2.`Group` AND t2.Breakpoint = 'B'
WHERE t2.ID IS NULL

对于每一行t1,尝试使用较早的ID在同一组中找到另一行“{1}”和“B”。如果未找到,则OUTER JOIN保证t2为NULL。只有在所需的断点之前,这才会成立。

答案 2 :(得分:0)

SQL表代表无序集。因此,特定行没有“之前”或“之后”。

我假设您有一些指定排序的列。我称之为id。然后你可以做你想做的事情:

select t.*
from t
where t.id < (select min(t2.id) from t t2 where t2.group = t.group and t2.breakpoint = 'B');

如果没有'B',则获取所有行:

select t.*
from t
where t.id < (select coalesce(min(t2.id), t.id + 1) from t t2 where t2.group = t.group and t2.breakpoint = 'B');

答案 3 :(得分:0)

您可以使用NOT EXISTS

select *
from your_table t1
where not exists (
  select 1
  from your_table t2
  where t1.group = t2.group and t2.id <= t1.id and t2.breakpoint = 'B'
)
如果ALL

中没有NULL

id也可以正常工作

select *
from your_table t1
where t1.id < ALL(
  select t2.id
  from your_table t2
  where t1.group = t2.group and t2.breakpoint = 'B'
)

答案 4 :(得分:0)

假设我们按ID列排序,我们可以这样做:

 SELECT d.*
   FROM mytable d
   LEFT
   JOIN ( SELECT bp.group
               , MIN(bp.id) AS bp_id
            FROM mytable bp
           WHERE bp.breakpoint = 'B'
           GROUP BY bp.group
        ) b
     ON b.group = d.group
  WHERE b.bp_id > d.id OR b.bp_id IS NULL 
  ORDER BY d.group, d.id

这会考虑给定breakpoint='B'没有group行的情况,并返回group的所有行。

请注意,内联视图b为每个id的{​​{1}}行提供了最低breakpoint='B'值。我们可以将它连接到原始表(匹配group),然后在WHERE子句中进行条件测试,以排除每个组的第一个group之后的行。