我需要执行查询(Oracle Select)以获取行,直到特定列的值更改而又不知道该值
假设我们有下表:
1 - AAAA - kkkk
2 - BBBB - kkkk
3 - CCCC - kkkk
4 - DDDD - kkkk
5 - EEEE - xxxx
6 - FFFF - xxxx
在第三列上,我只需要获取第1,2,3,4行(因为第5行和第6行的第三列的值发生了变化)。我事先不知道值kkkk和xxxx,所以我无法实现特定的条件。
非常感谢
答案 0 :(得分:3)
使用分层查询:
Oracle 11g R2架构设置:
CREATE TABLE table_name ( col1, col2 , col3 ) As
SELECT 1, 'AAAA', 'kkkk' FROM DUAL UNION ALL
SELECT 2, 'BBBB', 'kkkk' FROM DUAL UNION ALL
SELECT 3, 'CCCC', 'kkkk' FROM DUAL UNION ALL
SELECT 4, 'DDDD', 'kkkk' FROM DUAL UNION ALL
SELECT 5, 'EEEE', 'xxxx' FROM DUAL UNION ALL
SELECT 6, 'FFFF', 'xxxx' FROM DUAL;
查询1 :
SELECT *
FROM table_name
START WITH col1 = 1
CONNECT BY PRIOR col1 + 1 = col1
AND PRIOR col3 = col3
Results :
| COL1 | COL2 | COL3 |
|------|------|------|
| 1 | AAAA | kkkk |
| 2 | BBBB | kkkk |
| 3 | CCCC | kkkk |
| 4 | DDDD | kkkk |
答案 1 :(得分:3)
另一种方法是使用Tabibitosan,如下所示:
WITH your_table AS (SELECT 1 col1, 'AAAA' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 2 col1, 'BBBB' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 3 col1, 'CCCC' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 4 col1, 'DDDD' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 5 col1, 'EEEE' col2, 'xxxx' col3 FROM DUAL UNION ALL
SELECT 6 col1, 'FFFF' col2, 'xxxx' col3 FROM DUAL)
SELECT col1,
col2,
col3
FROM (SELECT col1,
col2,
col3,
row_number() OVER (ORDER BY col1) - row_number() OVER (PARTITION BY col3 ORDER BY col1) grp
FROM your_table)
WHERE grp = 0;
COL1 COL2 COL3
---------- ---- ----
1 AAAA kkkk
2 BBBB kkkk
3 CCCC kkkk
4 DDDD kkkk
第二行与第一行不同的示例:
WITH your_table AS (SELECT 1 col1, 'AAAA' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 2 col1, 'BBBB' col2, 'aaaa' col3 FROM DUAL UNION ALL
SELECT 3 col1, 'CCCC' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 4 col1, 'DDDD' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 5 col1, 'EEEE' col2, 'xxxx' col3 FROM DUAL UNION ALL
SELECT 6 col1, 'FFFF' col2, 'xxxx' col3 FROM DUAL)
SELECT col1,
col2,
col3
FROM (SELECT col1,
col2,
col3,
row_number() OVER (ORDER BY col1) - row_number() OVER (PARTITION BY col3 ORDER BY col1) grp
FROM your_table)
WHERE grp = 0;
COL1 COL2 COL3
---------- ---- ----
1 AAAA kkkk
我建议您测试所提供的所有解决方案,以找出对数据更有效的解决方案。
ETA:如果在您的实际数据中,有希望单独应用的组,则只需将相关列添加到两个row_number()分析函数的PARTITION BY子句中,例如:
WITH your_table AS (SELECT 1 id, 1 col1, 'AAAA' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 1 id, 2 col1, 'BBBB' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 1 id, 3 col1, 'CCCC' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 1 id, 4 col1, 'DDDD' col2, 'kkkk' col3 FROM DUAL UNION ALL
SELECT 1 id, 5 col1, 'EEEE' col2, 'xxxx' col3 FROM DUAL UNION ALL
SELECT 1 id, 6 col1, 'FFFF' col2, 'xxxx' col3 FROM DUAL UNION ALL
SELECT 2 id, 7 col1, 'GGGG' col2, 'aaaa' col3 FROM DUAL UNION ALL
SELECT 3 id, 8 col1, 'HHHH' col2, 'cccc' col3 FROM DUAL UNION ALL
SELECT 2 id, 9 col1, 'IIII' col2, 'bbbb' col3 FROM DUAL UNION ALL
SELECT 3 id, 10 col1, 'JJJJ' col2, 'cccc' col3 FROM DUAL UNION ALL
SELECT 2 id, 11 col1, 'KKKK' col2, 'aaaa' col3 FROM DUAL UNION ALL
SELECT 3 id, 12 col1, 'LLLL' col2, 'cccc' col3 FROM DUAL)
SELECT id,
col1,
col2,
col3
FROM (SELECT id,
col1,
col2,
col3,
row_number() OVER (PARTITION BY ID ORDER BY col1) - row_number() OVER (PARTITION BY id, col3 ORDER BY col1) grp
FROM your_table)
WHERE grp = 0
ORDER BY ID, col1;
ID COL1 COL2 COL3
---------- ---------- ---- ----
1 1 AAAA kkkk
1 2 BBBB kkkk
1 3 CCCC kkkk
1 4 DDDD kkkk
2 7 GGGG aaaa
3 8 HHHH cccc
3 10 JJJJ cccc
3 12 LLLL cccc
答案 2 :(得分:3)
再使用递归CTE比较性能:
with r (col1, col2, col3) as (
select col1, col2, col3
from your_table
where col1 = 1
union all
select t.col1, t.col2, t.col3
from r
join your_table t on t.col1 = r.col1 + 1 and t.col3 = r.col3
)
select * from r
order by col1;
COL1 COL2 COL3
---------- ---- ----
1 AAAA kkkk
2 BBBB kkkk
3 CCCC kkkk
4 DDDD kkkk
这基本上等同于@MTO的层次查询,只是实现此问题的另一种方式。正如@Boneist所说,将所有内容都洗一下,看看最适合您的实际情况的
。这两个都假设col1
的值从1开始并且是连续的,这就是您在示例数据中所显示的。如果不是这种情况,那么采用这种方法会更加复杂。但是Tabibitosan方法仍然可以使用。