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

Mysql 如何从组中选择所有行,直到出现值,mysql,sql,Mysql,Sql,我试图从相同的组中提取所有行,直到达到断点值B。下面的示例数据是有序虚拟表: +----+--------+------------+ | ID | Group | Breakpoint | +----+--------+------------+ | 1 | 1 | A | | 2 | 1 | A | | 3 | 1 | B | | 4 | 1 | A | | 5 | 2

我试图从相同的
组中提取所有行
,直到达到断点值
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          |
+----+--------+------------+
请注意,当一个组中同时存在
A
B
断点值时,我希望按此顺序保留第一个
A
值之前的行。如果像
group2
这样的组只有
A
值,我希望该组中的所有项目都是
SQL表表示无序集。因此,不存在特定行的“before”或“after”

假设您有一列指定了排序。我叫它
id
。然后,您可以使用以下工具执行您想要的操作:

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

从上面的示例中,您并没有真正对结果进行分组。您只需显示断点为以下位置的记录:

Select * From Table
Where Breakpint ='A'

您可以使用
不存在

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'
)

假设我们是按
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

这将考虑给定的
没有
断点class='B'
行的情况,并返回该
组的所有行


请注意,内联视图
b
为每个
从带有
breakpoint='b'
的行中获取最低的
id
值。我们可以将其外部联接到原始表(在
组上进行匹配),然后在WHERE子句中进行条件测试,以排除每个组在第一个
断点class='B'
之后的行。

下面是一个简单的解决方案,它不使用子查询或按逻辑分组

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
,尝试在同一组中找到另一行
t2
,该行具有较早的ID。如果没有找到,则外部联接保证
t2.ID
为空。只有在达到所需的断点之前,才会出现这种情况。

主键是什么?对不起,这是一个虚拟表结果,我在上面的示例中添加了一个唯一键!也许我们从一开始就开始……您使用的是什么服务器/Db?为什么ID 4被排除在外?@TommyO:
ID=4
没有进入预期的输出,因为前面的一行
ID=3
(对于相同的
)具有
断点
。我想OP应该停在第一个“B”之前的最后一排。我认为这就是OP将该列标记为“断点”的原因。当我们击中第一个“B”时,我们“断开”;我们已经完成了对该组的处理。当没有断点为'B'
的行时,OP似乎希望返回所有行。我认为这个查询排除了这些行。(请参见OP示例数据中的
group=2
行和预期输出。)注意,此查询将返回从OP示例输出中排除的行
id=4
 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
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