Если вы используете LISTAGG, есть предостережение с LISTAGG в том, что он игнорирует значения NULL. Вы уверены, что ваша колонка ВСЕГДА будет иметь данные? Если, скажем, test_sensor2 равен NULL, выходной результат операции listagg будет 20,40,50,60,70
, поэтому после значения NULL все данные датчика будут сообщены неверно! Исправьте это, используя это:
replace(LISTAGG( nvl(to_char(ColumnA), ','), ',' )
WITHIN GROUP ( ORDER BY ColumnB ), ',,,',',,')
Теперь ваш вывод равен 20,,40,50,60,70
, сохраняя значение NULL для test_sensor2, а остальные в правильном положении.
ОДНАКО теперь существует другая проблема в том, что регулярное выражение формы '[^,]+'
вызывает ту же проблему! Таким образом, даже несмотря на то, что вывод listagg фиксирован, анализируемый вывод снова отключается после столбца со значением NULL! Ниже показана другая форма, которая решает эту проблему. Вот пример, настроенный таким образом, что вы можете комментировать / раскомментировать, чтобы увидеть различия при обработке данных. Всегда ожидай неожиданного!
with TableA ( ColumnA, ColumnB, ColumnC ) AS (
SELECT 20, 'A', 'Z12345' FROM DUAL UNION ALL
SELECT NULL, 'B', 'Z12345' FROM DUAL UNION ALL -- make NULL
SELECT 40, 'C', 'Z12345' FROM DUAL UNION ALL
SELECT 50, 'D', 'Z12345' FROM DUAL UNION ALL
SELECT 60, 'E', 'Z12345' FROM DUAL UNION ALL
SELECT 70, 'F', 'Z12345' FROM DUAL
),
tbl_tmp as (
SELECT ColumnC,
-- Preserve the NULL in position 2
replace(LISTAGG( nvl(to_char(ColumnA), ','), ',' )
WITHIN GROUP ( ORDER BY ColumnB ), ',,,',',,')
AS test_sensor
FROM TableA
GROUP BY ColumnC
)
--select * from tbl_tmp;
-- regex of format [^,]+ does not handle NULLs
SELECT ColumnC,
-- REGEXP_SUBSTR( test_sensor, '[^,]+', 1, 1) AS test_sensor1,
-- REGEXP_SUBSTR( test_sensor, '[^,]+', 1, 2 ) AS test_sensor2,
-- REGEXP_SUBSTR( test_sensor, '[^,]+', 1, 3 ) AS test_sensor3,
-- REGEXP_SUBSTR( test_sensor, '[^,]+', 1, 4 ) AS test_sensor4
REGEXP_SUBSTR( test_sensor, '(.*?)(,|$)', 1, 1, NULL, 1) AS test_sensor1,
REGEXP_SUBSTR( test_sensor, '(.*?)(,|$)', 1, 2, NULL, 1 ) AS test_sensor2,
REGEXP_SUBSTR( test_sensor, '(.*?)(,|$)', 1, 3, NULL, 1 ) AS test_sensor3,
REGEXP_SUBSTR( test_sensor, '(.*?)(,|$)', 1, 4, NULL, 1 ) AS test_sensor4
FROM tbl_tmp;