假设您有某种列来确定结果集的顺序(例如,下面我的查询中的 id 列),这很容易使用称为 Tabibitosan 的技术来完成:
WITH sample_data AS (SELECT 1 ID, 'A' NAME, 'D' flag FROM dual UNION ALL
SELECT 2 ID, 'B' NAME, 'D' flag FROM dual UNION ALL
SELECT 3 ID, 'C' NAME, 'D' flag FROM dual UNION ALL
SELECT 4 ID, 'D' NAME, 'I' flag FROM dual UNION ALL
SELECT 5 ID, 'E' NAME, 'I' flag FROM dual UNION ALL
SELECT 6 ID, 'D' NAME, 'D' flag FROM dual UNION ALL
SELECT 7 ID, 'E' NAME, 'D' flag FROM dual UNION ALL
SELECT 8 ID, 'B' NAME, 'I' flag FROM dual UNION ALL
SELECT 9 ID, 'D' NAME, 'I' flag FROM dual UNION ALL
SELECT 10 ID, 'F' NAME, 'I' flag FROM dual)
SELECT ID,
NAME,
flag
FROM (SELECT ID,
NAME,
flag,
grp,
MIN(CASE WHEN flag = 'D' THEN grp END) OVER (PARTITION BY flag) min_d_grp,
MAX(CASE WHEN flag = 'I' THEN grp END) OVER (PARTITION BY flag) max_i_grp
FROM (SELECT ID,
NAME,
flag,
row_number() OVER (ORDER BY ID) - row_number() OVER (PARTITION BY flag ORDER BY ID) grp
FROM sample_data
WHERE flag IN ('D', 'I')))
WHERE (flag = 'D' AND grp = min_d_grp)
OR (flag = 'I' AND grp = max_i_grp)
ORDER BY id;
ID NAME FLAG
---------- ---- ----
1 A D
3 C D
2 B D
9 D I
8 B I
10 F I
此查询使用 tabibitosan 方法生成一个额外的“grp”列,然后您可以使用该列查找 D 标志行的最低编号和 I 标志行的最高编号。
ETA:这可能会或可能不会比 Gordon 的答案表现更好,但我建议您测试两个答案,看看哪个更适合您的表/索引/数据等。