查询数据库中的行,直到值更改

时间:2018-06-28 09:15:26

标签: sql oracle select

我需要执行查询(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,所以我无法实现特定的条件。

非常感谢

3 个答案:

答案 0 :(得分:3)

使用分层查询:

SQL Fiddle

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方法仍然可以使用。