В поддерживаемой мною программе заказчик получил массивное (~ 500 строк) SQL-выражение. Он используется для создания плоских файлов с записями фиксированной длины для передачи данных другому крупному бизнесу. Поскольку это массивный плоский файл, его нереляционные и стандартные нормальные формы данных свернуты. Итак, если у вас есть запись, с которой может быть связано несколько кодов, в данном случае до 19, все они будут записаны в одну строку, а отдельные поля - в плоский файл.
Примечание: этот пример упрощен.
Данные могут выглядеть так с тремя таблицами:
RECORDS
record_id firstname lastname
--------------------------------
123 Bob Schmidt
324 George Washington
325 Ronald Reagan
290 George Clooney
CODE_TABLE
code_id code_cd code_txt
--------------------------------
5 3 President
2 4 Actor
3 7 Plumber
CODES_FOR_RECORDS
record_id code_cd
-------------------
123 7
325 3
290 4
324 3
325 4
123 4
Для этого нужно создать такие записи, как:
firstname lastname code1 code2 code3
Bob Schmidt Actor Plumber NULL
George Washington President NULL NULL
Ronald Reagon Actor President NULL
George Clooney Actor NULL NULL
Часть текущего запроса, которую нам дали, выглядит следующим образом, но с 19 столбцами кода вместо 5:
select
x.record_id,
max(case when x.rankk = 1 then code_txt end) as CodeColumn1,
max(case when x.rankk = 2 then code_txt end) as CodeColumn2,
max(case when x.rankk = 3 then code_txt end) as CodeColumn3,
max(case when x.rankk = 4 then code_txt end) as CodeColumn4,
max(case when x.rankk = 5 then code_txt end) as CodeColumn5,
from
(
select
r.record_id,
ct.code_txt as ctag ,
dense_rank() over (partition by r.record_id order by cfr.code_id) as rankk
from
records as r
codes_for_records as cfr,
code_table as ct
where
r.record_id = cfr.record_id
and ct.code_cd = cfr.code_cd
and cfr.code_cd is not null
and ct.code_txt not like '%V%'
) as x
where
x.record_id is not null
group by
x.record_id
Я упустил некоторые вещи для простоты, но фактическая оценка включает в себя внутренний запрос и объединение, а также другие условия, но это должно помочь понять идею. Мой мозг говорит мне, что должен быть лучший путь, но я не эксперт по SQL. Мы используем DB2 v8, если это поможет. И коды должны быть в отдельных столбцах, так что не объединяйте вещи в одну строку. Есть ли более чистое решение, чем это?
Обновление:
В итоге я просто рефакторировал исходный запрос, он все-таки использует уродливую функцию MAX (), но в целом запрос гораздо более читабелен благодаря переработке других частей.