Dans un programme que je conserve, le client nous a donné une instruction SQL massive (~ 500 lignes). Il est utilisé pour générer des fichiers plats avec des enregistrements de longueur fixe pour la transmission de données à une autre grande entreprise. Comme c'est un fichier plat massif, il n'est pas relationnel et les formes normales de données sont réduites. Donc, si vous avez un enregistrement qui peut avoir plusieurs codes associés, dans ce cas jusqu'à 19, ils ont tous été écrits en une seule ligne, mais séparés, dans le fichier plat.Réduire plusieurs enregistrements dans un seul enregistrement avec plusieurs colonnes
Remarque: cet exemple est simplifié.
Les données pourraient ressembler à ceci, avec trois tables:
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
Cela doit produire des documents tels que:
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
La partie de la requête en cours nous a donné ressemble à ceci, mais avec 19 colonnes de code au lieu de la 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
Je trimm édité des choses à des fins de simplicités, mais la déclaration réelle comprend une requête interne et une jointure et plus où les conditions, mais cela devrait faire passer l'idée. Mon cerveau me dit qu'il doit y avoir un meilleur moyen, mais je ne suis pas un expert SQL. Nous utilisons DB2 v8 si cela peut vous aider. Et les codes doivent être dans des colonnes séparées, donc pas de fusionner les choses en une seule chaîne. Y a-t-il une solution plus propre que celle-ci?
Mise à jour:
J'ai fini juste refacorting la requête initiale, il utilise le seuil de vilaine affaire MAX(), mais dans l'ensemble de la requête est beaucoup plus facile à lire en raison de retravailler d'autres parties.
Lorsque j'écris du code pour transformer des données manuellement, la procédure est rarement inférieure à 1 000 lignes. Ce code me semble assez simple et direct. – HLGEM
Peut-être que c'est que je ne suis pas vraiment familier avec SQL, parce que pour moi cela semble un peu compliqué. Et une partie de cela est de 1000 lignes lorsqu'il est séparé en morceaux logiques n'est pas mauvais. 500 lignes de SQL qui est tellement interconnecté il semble que spaghetti est une autre chose, à mon humble avis. – troutinator