Вы можете использовать рекурсивный подзапрос и простые строковые функции, чтобы разбить строку на времена, а затем использовать LISTAGG
, чтобы повторно объединить их упорядочение по возрастанию.
Тестовые данные :
CREATE TABLE test_data ( times ) AS
SELECT '0730PM:0600PM:0800PM' FROM DUAL UNION ALL
SELECT '0730PM:0730AM:0600PM' FROM DUAL UNION ALL
SELECT '0730PM:0730AM:0600PM' FROM DUAL UNION ALL
SELECT ( SELECT LISTAGG(
TO_CHAR( TRUNC( SYSDATE ) + ( LEVEL - 1 ) * INTERVAL '1' HOUR, 'HH12MIAM' ),
':'
) WITHIN GROUP ( ORDER BY DBMS_RANDOM.VALUE() )
FROM DUAL
CONNECT BY LEVEL <= 24 ) FROM DUAL;
Запрос :
WITH bounds ( rid, times, start_pos, end_pos ) AS (
SELECT ROWID,
times,
1,
INSTR( times, ':', 1 )
FROM test_data
UNION ALL
SELECT rid,
times,
end_pos + 1,
INSTR( times, ':', end_pos + 1 )
FROM bounds
WHERE end_pos > 0
),
time_strings ( rid, value ) AS (
SELECT rid,
CASE end_pos
WHEN 0
THEN SUBSTR( times, start_pos )
ELSE SUBSTR( times, start_pos, end_pos - start_pos )
END
FROM bounds
)
SELECT LISTAGG( value, ':' ) WITHIN GROUP ( ORDER BY TO_DATE( value, 'HH12MIAM' ) )
AS times
FROM time_strings
GROUP BY rid;
Выход :
| TIMES |
| :---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 0600PM:0730PM:0800PM |
| 0730AM:0600PM:0730PM |
| 0730AM:0600PM:0730PM |
| 1200AM:0100AM:0200AM:0300AM:0400AM:0500AM:0600AM:0700AM:0800AM:0900AM:1000AM:1100AM:1200PM:0100PM:0200PM:0300PM:0400PM:0500PM:0600PM:0700PM:0800PM:0900PM:1000PM:1100PM |
дБ <> скрипка здесь