SQL Fiddle
Если вы хотите сгруппировать значения с интервалом в 5 минут (например, 10: 45-10: 49, 10: 50-10: 54, 10: 55-11: 00 и т. Д.), То вы можете сделать:
Oracle 11g R2 Настройка схемы:
CREATE TABLE TEST (Col1, Col2, Time) AS
SELECT 'txt01', 'same0', TO_DATE('2015-06-29 10:49', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt02', 'same0', TO_DATE('2015-06-29 10:50', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt03', 'same0', TO_DATE('2015-06-29 10:51', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt04', 'same0', TO_DATE('2015-06-29 10:52', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt05', 'same0', TO_DATE('2015-06-29 10:53', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt06', 'same0', TO_DATE('2015-06-29 10:54', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt07', 'same0', TO_DATE('2015-06-29 10:55', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt08', 'same0', TO_DATE('2015-06-29 10:56', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt09', 'same0', TO_DATE('2015-06-29 16:30', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt10', 'same1', TO_DATE('2015-06-29 15:15', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt11', 'same2', TO_DATE('2015-06-29 16:31', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt12', 'same3', TO_DATE('2015-06-29 08:05', 'YYYY-MM-DD HH24:MI') FROM DUAL
UNION ALL SELECT 'txt13', 'same3', TO_DATE('2015-06-29 08:07', 'YYYY-MM-DD HH24:MI') FROM DUAL
Запрос 1:
SELECT LISTAGG(Col1, ',') WITHIN GROUP (ORDER BY Time) AS Col1,
Col2,
LISTAGG(TO_CHAR(Time, 'HH24:MI'), ',') WITHIN GROUP (ORDER BY Time) AS Time,
COUNT(1) AS "Count"
FROM TEST
GROUP BY
Col2,
TRUNC(Time),
FLOOR((TO_NUMBER(TO_CHAR(Time, 'HH24')) * 60 + TO_NUMBER(TO_CHAR(Time, 'MI')))/5)
Results:
| COL1 | COL2 | TIME | Count |
|-------------------------------|-------|-------------------------------|-------|
| txt01 | same0 | 10:49 | 1 |
| txt02,txt03,txt04,txt05,txt06 | same0 | 10:50,10:51,10:52,10:53,10:54 | 5 |
| txt07,txt08 | same0 | 10:55,10:56 | 2 |
| txt09 | same0 | 16:30 | 1 |
| txt10 | same1 | 15:15 | 1 |
| txt11 | same2 | 16:31 | 1 |
| txt12,txt13 | same3 | 08:05,08:07 | 2 |
Если вы хотите, чтобы группы до 5 строк, которые все в том же 5-минутный период и может начаться с любого времени, то вы можете использовать конвейерную функцию:
Oracle 11g R2 схему Установка:
CREATE TYPE TEST_GROUP_OBJ AS OBJECT(
Col1 VARCHAR2(54), -- 5 * Length of Col1 + 4
Col2 VARCHAR2(10), -- Length of Col2
Time VARCHAR2(29) -- 5 * Length of 'HH:MI' + 4
)
/
CREATE TYPE TEST_GROUP_TAB AS TABLE OF TEST_GROUP_OBJ
/
CREATE FUNCTION getFiveMinuteGroupings
RETURN TEST_GROUP_TAB PIPELINED
AS
TYPE TEST_TAB IS TABLE OF TEST%ROWTYPE;
t_test_tab TEST_TAB;
v_time TEST.TIME%TYPE;
v_grp TEST_GROUP_OBJ := TEST_GROUP_OBJ(NULL, NULL, NULL);
v_count NUMBER(1,0);
BEGIN
SELECT *
BULK COLLECT INTO t_test_tab
FROM TEST
ORDER BY Col2, Time;
IF t_test_tab.COUNT = 0 THEN
RETURN;
END IF;
v_time := t_test_tab(1).TIME;
v_grp.COL1 := t_test_tab(1).COL1;
v_grp.COL2 := t_test_tab(1).COL2;
v_grp.TIME := TO_CHAR(t_test_tab(1).TIME, 'HH24:MI');
v_count := 1;
FOR i IN 2 .. t_test_tab.COUNT LOOP
IF t_test_tab(i).COL2 = v_grp.COL2
AND t_test_tab(i).TIME <= v_time + INTERVAL '5' MINUTE
AND v_count < 5
THEN
v_grp.COL1 := v_grp.COL1 || ',' || t_test_tab(i).COL1;
v_grp.TIME := v_grp.TIME || ',' || TO_CHAR(t_test_tab(i).TIME, 'HH24:MI');
v_count := v_count + 1;
ELSE
PIPE ROW(v_grp);
v_time := t_test_tab(i).TIME;
v_grp.COL1 := t_test_tab(i).COL1;
v_grp.COL2 := t_test_tab(i).COL2;
v_grp.TIME := TO_CHAR(t_test_tab(i).TIME, 'HH24:MI');
v_count := 1;
END IF;
END LOOP;
PIPE ROW(v_grp);
END;
/
Запрос 2:
SELECT *
FROM TABLE(getFiveMinuteGroupings())
Results:
| COL1 | COL2 | TIME |
|-------------------------------|-------|-------------------------------|
| txt01,txt02,txt03,txt04,txt05 | same0 | 10:49,10:50,10:51,10:52,10:53 |
| txt06,txt07,txt08 | same0 | 10:54,10:55,10:56 |
| txt09 | same0 | 16:30 |
| txt10 | same1 | 15:15 |
| txt11 | same2 | 16:31 |
| txt12,txt13 | same3 | 08:05,08:07 |
Что бы группирование быть для 10: 48,10: 49,10: 50, 10:51, 10:52, 10:53, 10:54? –
также будет сгруппирован 16:30, 16:31 и 15:15? Как и все от 0 до 5 минут, все с 5,01 до 10 минут, все с 10,01 до 15 и все от 15-20 и т. Д. ...? –
@DavidAldridge Хороший отзыв, спасибо. В ситуации, о которой вы упомянули, я думаю, что максимум 5 баллов для этого хорош. Так что это должно быть 10: 48,10: 49,10: 50,10: 51,10: 52 в одной строке и 10:53, 10:54 в другой строке. –