如何从组中选择所有行,直到出现值
我试图从同一个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 |
+----+--------+------------+
注意,当有一组内两个A
和B
断点值,我想有行,直到顺序第一A
值。如果像group 2
这样的组中只有A
的值,我想拥有组中的所有项目。
这是一个简单的解决方案,不使用子查询或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
,试图找到与“B”的另一行t2
,在同一组,与先前的ID。如果没有找到,则OUTER JOIN保证t2.ID
为NULL。只有等到理想的断点后,情况才会如此。
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');
当不存在具有'breakpoint ='B''的行时,看起来像OP想要返回所有行。我认为这个查询排除了这些行。 (请参阅OP示例数据中的group = 2行,以及期望的输出。) – spencer7593
从你上面的例子,你是不是真的分组结果。你只需要显示的记录,其中断点答:
Select * From Table
Where Breakpint ='A'
请注意,此查询将返回从OP示例输出中排除的行id = 4。 – spencer7593
您可以使用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'
)
假设我们按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
从breakpoint='B'
行获得的最低id
值为每个group
。我们可以将外部联接添加到原始表(匹配group
),然后在WHERE子句中进行条件测试,以排除每个组的第一个breakpoint='B'
后面的行。
你的PRIMARY KEY是什么? – Strawberry
对不起,这是一个虚拟表结果,我在上面的例子中添加了一个唯一的键! – ddinchev
也许如果我们从头开始.... – Strawberry