Запрос базы данных для строк до изменения значения - PullRequest
0 голосов
/ 28 июня 2018

Мне нужно выполнить запрос (выбор Oracle), чтобы получить строки, пока значение определенного столбца не изменится, не зная этого значения

Допустим, у нас есть следующая таблица:

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 голосов
/ 28 июня 2018

Другой способ будет использовать Табибитозан , например:

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: если в ваших реальных данных есть группы, к которым вы хотите применить это отдельно, вам просто нужно добавить соответствующие столбцы в предложения PARTITION BY двух аналитических функций row_number (), например:

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
0 голосов
/ 28 июня 2018

Еще одно сравнение производительности с использованием рекурсивного 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 и являются смежными, что вы и показали в примерах данных. Если это не так, то с таким подходом все будет немного сложнее; но метод Табибитозан будет работать в любом случае.

0 голосов
/ 28 июня 2018

Использовать иерархический запрос:

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

Результаты

| COL1 | COL2 | COL3 |
|------|------|------|
|    1 | AAAA | kkkk |
|    2 | BBBB | kkkk |
|    3 | CCCC | kkkk |
|    4 | DDDD | kkkk |
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...