2017-02-04 1 views
0

У меня есть проблема, которую нужно решить с помощью sql в oracle.sql-запрос для получения уникального идентификатора для строки в оракуле на основе его непрерывности

У меня есть набор данных, как приведено ниже:

value | date 
------------- 
1 | 01/01/2017 
2 | 02/01/2017 
3 | 03/01/2017 
3 | 04/01/2017 
2 | 05/01/2017 
2 | 06/01/2017 
4 | 07/01/2017 
5 | 08/01/2017 

мне нужно показать результат в указанном ниже формате:

value | date  | Group 
1 | 01/01/2017 | 1 
2 | 02/01/2017 | 2 
3 | 03/01/2017 | 3 
3 | 04/01/2017 | 3 
2 | 05/01/2017 | 4 
2 | 06/01/2017 | 4 
4 | 07/01/2017 | 5 
5 | 08/01/2017 | 6 

Логика когда value изменения за date, он получает назначен новый group/id, но если он такой же, как и предыдущий, то его часть того же group.

+0

Какова логика, которая преобразует то, что вам нужно, что вы хотите? – BobC

+0

Логика всякий раз, когда значение меняет дату, ему присваивается новая группа/id, но если она такая же, как и предыдущая, то ее часть той же группы. Надеюсь это поможет. – amit

+0

Amit - то, что у вас есть в комментарии, должно быть добавлено к вашему сообщению. Я сделал это для вас на этот раз, но, пожалуйста, помните, что в будущем - любое дальнейшее уточнение требований, ввода или вывода, а также дополнительный код, который вы предоставляете и т. Д., Должны находиться в теле вашего сообщения; используйте комментарии, чтобы предупредить других о том, что вы редактировали сообщение. Спасибо! – mathguy

ответ

0

Вот один метод с использованием lag() и нарастающего итога:

select t.*, 
     sum(case when value = prev_value then 0 else 1 end) over (order by date) as grp 
from (select t.*, 
      lag(value) over (order by date) as prev_value 
     from t 
    ) t; 

Логика здесь просто подсчитать количество раз, что значение изменяется от одного месяца к другому.

Предполагается, что date фактически хранится как дата, а не строка. Если это строка, то упорядочение будет неправильным. Либо конвертируйте в дату, либо используйте столбец, который задает правильный порядок.

+0

Спасибо, что было очень полезно – amit

0

Вот решение, используя пункт MATCH_RECOGNIZE, введенный в Oracle 12 *

select value, dt, mn as grp 
from inputs 
match_recognize (
    order by dt 
    measures match_number() as mn 
    all rows per match 
    pattern (a b*) 
    define b as value = prev(value) 
) 
order by dt -- if needed 
; 

Вот как это работает: Другие, чем SELECT, FROM и ORDER BY, запрос содержит только один пункт, MATCH_RECOGNIZE. То, что делает этот пункт, это: он берет строки от inputs и заказывает их dt. Затем он ищет шаблоны: одну строку, помеченную как a, без ограничений, за которой следуют ноль или несколько строк b, где b определяется условием, что value является тем же, что и для предыдущей строки. То, что вычисляет предложение, или measures - это match_number() - первое «совпадение» шаблона, второго совпадения и т. Д. Мы используем этот номер совпадения как номер группы (grp) во внешнем запросе - это все, что нам нужно!

* Примечания: Существование таких решений показывает, почему для плакатов важно указать свою версию Oracle. (Запустите оператор select * from v$version, чтобы узнать.) Также: date и group зарезервированы слова в Oracle и не должны использоваться в качестве имен столбцов. Даже для публикации собранных образцов данных. (Есть обходные пути, но в этом случае они не нужны.) Кроме того, всякий раз, когда вы использовали даты, такие как 03/01/2017 в сообщении, пожалуйста, укажите, является ли это 1 марта или 3 января, нет возможности «нам» сказать , (В этом случае это было неважно, но это в подавляющем большинстве случаев.)

Смежные вопросы