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。 –