Fusionner plusieurs lignes en une avec plus d'une valeur de ligne dans une colonne
Je construis actuellement une requête pour récupérer des données de ma base de données, j'ai besoin d'accéder à certaines informations avec un identifiant commun sur une seule ligne.
Avec cette requête:
select
missions_answer.response_id as "response",
crm_player."document" as "document",
missions_question.label as "label",
missions_answertext.body as "bill #",
missions_answerselectmultiple.body as "product",
missions_answerinteger.body as "answer"
from missions_answer
left join missions_question on missions_answer.question_id = missions_question.id
left join missions_answertext on missions_answer.id = missions_answertext.answer_ptr_id
left join missions_answerselectmultiple on missions_answer.id = missions_answerselectmultiple.answer_ptr_id
left join missions_answerinteger on missions_answer.id = missions_answerinteger.answer_ptr_id
left join missions_response on missions_answer.response_id = missions_response.id
left join crm_player on missions_response.player_id = crm_player.id
LEFT JOIN crm_user ON crm_player.user_id = crm_user.id
where missions_answer.response_id = '71788176'
group by missions_answer.response_id, crm_player.document,missions_answertext.body,
missions_question.label,
missions_answerselectmultiple.body ,
missions_answerinteger.body,
crm_user.first_name,
crm_user.last_name
Voici ce que j'ai actuellement:
+ response + document + label + bill # + product + answer
- 71788176 - 79907201 - bill # - 26899 - -
- 71788176 - 79907201 - amount - - - 1
- 71788176 - 79907201 - product - - {"name": "Shoes"} -
- 71788176 - 79907201 - price - - - 25.99
Voici ce que je recherche:
+ response + document + bill # + product + amount + price
- 71788176 - 79907201 - 26899 - shoes - 1 - 25.99
J'ai essayé de l'utiliser crosstab
mais je ne parviens toujours pas à le trouver, merci d'avance pour toute indication ou aide.
Réponses
À partir de votre état actuel, vous pouvez simplement faire le pivot en utilisant la FILTER
clause:
démo: db <> fiddle
SELECT
response,
document,
MAX(bill) FILTER (WHERE label = 'bill') as bill,
MAX(answer) FILTER (WHERE label = 'amount') as amount,
MAX(product) FILTER (WHERE label = 'product') as product,
MAX(answer) FILTER (WHERE label = 'price') as price
FROM t
GROUP BY response, document
Je ne sais pas trop à quoi ressemble votre table d'origine. Si c'est plus comme ça:
response | document | label | value
-------: | -------: | :------ | :----
71788176 | 79907201 | bill | 26899
71788176 | 79907201 | amount | 1
71788176 | 79907201 | product | shoes
71788176 | 79907201 | price | 25.99
Ensuite, vous pouvez modifier la requête comme ceci:
démo: db <> fiddle
SELECT
response,
document,
MAX(value) FILTER (WHERE label = 'bill') as bill,
MAX(value) FILTER (WHERE label = 'amount') as amount,
MAX(value) FILTER (WHERE label = 'product') as product,
MAX(value) FILTER (WHERE label = 'price') as price
FROM t
GROUP BY response, document
Edit : Pour ajouter la valeur JSON à la colonne de produit:
démo: db <> fiddle
Variante 1: vous pouvez simplement json
convertir le type en type text
:
MAX(product::text) FILTER (WHERE label = 'product') as product,
Variante 2: vous lisez la valeur de l' "name"
attribut:
MAX(product ->> 'name') FILTER (WHERE label = 'product') as product,