web-dev-qa-db-fra.com

Comment transformer des données verticales en données horizontales avec SQL?

J'ai un tableau "Item" avec un certain nombre d'articles liés, comme ceci:

ID   Rel_ID  Name  RelRank
---  ------  ----  -------
1    1       foo   1
2    1       bar   2
3    1       zam   3
4    2       foo2  1

J'essaie d'obtenir une requête afin que les éléments avec le même Rel_ID apparaissent sur la même ligne, comme ceci:

Rel_ID  Name1  Name2  Name3
------  -----  -----  -----
1       foo    bar    zam
2       foo2

J'ai essayé de sélectionner la table plusieurs fois:

SELECT k.Rel_ID, k.name 'Name1', k2.name 'Name2'
FROM item k, item k2
WHERE k.Rel_ID = k2.Rel_ID

Mais cela échoue. Il y a sûrement une transformation ou une requête qui pourrait considérablement simplifier le processus, et je la manque juste parce que je n'ai jamais utilisé SQL de cette manière auparavant. Qu'est-ce que je rate?

[Edit: ajout de la colonne RelRank, qui apparaît dans mes données]

18
Dan

Indépendamment de la base de données que vous utilisez, le concept de ce que vous essayez d’atteindre est appelé "tableau croisé dynamique".

Voici un exemple pour mysql: http://en.wikibooks.org/wiki/MySQL/Pivot_table

Certaines bases de données ont des fonctionnalités intégrées pour cela, voir les liens ci-dessous.

SQLServer: http://msdn.Microsoft.com/de-de/library/ms177410.aspx

Oracle: http://www.dba-Oracle.com/t_pivot_examples.htm

Vous pouvez toujours créer un pivot à la main. Il suffit de sélectionner toutes les agrégations d'un ensemble de résultats, puis de sélectionner cet ensemble de résultats. Notez que dans votre cas, vous pouvez mettre tous les noms dans une colonne avec concat (je pense que c'est group_concat dans mysql), car vous ne pouvez pas savoir combien de noms sont associés à un rel_id.

pseudo-select pour votre cas (je ne connais pas mysql):

select rel_id, group_concat(name) from item group by rel_id
19
Falcon

Je pense que vous recherchez une réponse spécifique à MySQL . N'oubliez pas que la syntaxe peut varier selon les magasins de données.

MySQL a une fonctionnalité qui facilite cette tâche.

SELECT Rel_ID, GROUP_CONCAT(Name SEPARATOR ' ') As Names FROM Item GROUP BY Rel_ID;

cela devrait fonctionner :-)

3
smartnut007

si les noms que vous avez listés sont statiques, la requête ci-dessous que j'ai exécutée avec succès dans sqlfiddle fonctionnera

SELECT rel_id,
MAX (DECODE (rel_id, '1', DECODE (relrank, '1', name) , '2',DECODE (relrank, '1', name))) NAME1,
MAX (DECODE (rel_id, '1', DECODE (relrank, '2', name))) NAME2,
MAX (DECODE (rel_id, '1', DECODE (relrank, '3', name))) NAME3
FROM supportContacts
GROUP BY rel_id

heres le violon SQL 

http://sqlfiddle.com/#!4/480e2/11

0
sayannayas