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