2013-02-16 2 views
-4

У меня есть эта таблица:Группировки аналогичной последовательности записей, сохраняя порядок

day point deltatime order 
8  5  2   1 
8  7  1   2 
8  3  4   3 
8  2  2   4 
9  5  2   1 
9  7  2   2 
9  3  3   3 
9  2  2   4 
5  5  2   1 
5  7  1   2 
5  3  4   3 
5  2  2   4 
3  5  2   1 
3  7  2   2 
3  3  3   3 
3  2  2   4 

Мне нужна (эффективный) оракул запрос для получения (возможно без декларирования функций):

dayaggr point deltatime order 
8,5  5  2   1 
8,5  7  1   2 
8,5  3  4   3 
8,5  2  2   4 
9,3  5  2   1 
9,3  7  2   2 
9,3  3  3   3 
9,3  2  2   4 

Итак: мне нужно для объединения дней, основанных на идентичных последовательностях записей, сохраняя порядок. Решения, использующие LISTAGG, являются предпочтительными. Спасибо заранее.

+2

Это невозможно расшифровать. Пожалуйста, покажите схему таблицы с типами данных и т. Д., Строками выборки и ожидаемым результатом в более читаемом формате. Вы получите дополнительную помощь, если потратите немного больше времени на построение лучшего вопроса. – OldProgrammer

ответ

2

так:

SQL> select listagg(d.day,',') within group(order by 1) days, point, deltatime, ordr 
    2 from data d 
    3   inner join (select day, listagg(point||':'||deltatime||':'||ordr,',') within group (order by ordr) grp 
    4      from data 
    5      group by day) grp 
    6     on grp.day = d.day 
    7 group by point, deltatime, ordr, grp 
    8 order by days desc, ordr; 

DAYS   POINT DELTATIME  ORDR 
---------- ---------- ---------- ---------- 
5,8     5   2   1 
5,8     7   1   2 
5,8     3   4   3 
5,8     2   2   4 
3,9     5   2   1 
3,9     7   2   2 
3,9     3   3   3 
3,9     2   2   4 

8 rows selected. 

нет никакого надежного способа учитывая ваши данные «сохранить порядок», если вы ссылаетесь на «дни», поэтому я заказал просто days desc

скрипкой: http://sqlfiddle.com/#!4/3ea17/2

+0

Порядок дней не важен; ваше решение работает, но listagg (point || ':' || deltatime || ':' || ordr, ',') может стать слишком длинным (не знаю, имеет ли он ограничение по размеру) для моих реальных данных: в примере я показал только 4 строки на группу, но я мог бы иметь более 100; далее у меня есть более трех полей (point, deltatime, ordr), у меня могло бы быть 10-12 для конкатенации. – ascattolini

+0

@ user2079010 - «не знаю, имеет ли он ограничение по размеру». LISTAGG() возвращает varchar2, поэтому его предел: возвращаемое значение должно быть <= 4000 символов. «У меня могло бы быть 10-12, чтобы объединиться». И ваша точка зрения? – APC

+0

@ user2079010 Существует несколько различных методов агрегации строк для строк размером более 4000 символов. Или вы можете использовать хэш разных столбцов. (Что не всегда тривиально - вам нужно хэшировать сумму хэша каждого столбца плюс позицию столбца. Это гарантирует, что измененные значения не будут считаться одинаковыми.) Но в любом случае этот метод должен работать. –

0

Попробуйте это:

SELECT 
    LISTAGG(day, ',') WITHIN GROUP (ORDER BY point, deltatime, order) "dayaggr", 
    point, deltatime, order 
    FROM MyTable 
    GROUP BY point, deltatime, order; 
+0

Это не работает: я получил 3,5,8,9, когда (точка, дельтатим, порядок) = (2,2,4) или (5,2,1) – ascattolini

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