我正在尝试从同一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
值。如果A
中的某个组只有group 2
个值,我希望该组中包含所有项目。
答案 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
之后的行。