web-dev-qa-db-fra.com

MySQL: Comment joindre plusieurs fois la même table?

J'ai deux tables ticket et attr. La table ticket a ticked_id champ et plusieurs autres champs. La table attr comporte 3 champs:

ticket_id - numeric
attr_type - numeric
attr_val - string

attr_type est une énumération fixe de valeurs. Par exemple, il peut s'agir de 1, 2 ou 3.

J'ai besoin de faire une requête, dont le résultat sera de 4 colonnes:

ticket_id, attr_val pour attr_type=1, attr_val pour attr_type=2, attr_val pour attr_type=3

S'il n'y a pas de valeur correspondante pour attr_type dans la table attr alors la valeur NULL doit être affichée dans la colonne correspondante.

Exemple:

ticket
    ticket_id: 1

    ticket_id: 2

    ticket_id: 3


attr
    ticket_id: 1
    attr_type: 1
    attr_val: Foo

    ticket_id: 1
    attr_type: 2
    attr_val: Bar

    ticket_id: 1
    attr_type: 3
    attr_val: Egg

    ticket_id: 2
    attr_type: 2
    attr_val: Spam

le résultat devrait être:

ticked_id: 1
attr_val1: Foo
attr_val2: Bar
attr_val3: Egg

ticked_id: 2
attr_val1: NULL
attr_val2: Spam
attr_val3: NULL

ticked_id: 3
attr_val1: NULL
attr_val2: NULL
attr_val3: NULL

J'ai essayé de joindre la table attr à 3 reprises, mais je n'arrive pas à comprendre comment organiser la sortie par attr_type

29
rmflow

Vous devez utiliser plusieurs LEFT JOINs:

SELECT 
    ticket.ticket_id,  
    a1.attr_val AS attr_val1,
    a2.attr_val AS attr_val2,
    a3.attr_val AS attr_val3
FROM ticket
    LEFT JOIN attr a1 ON ticket.ticket_id=a1.ticket_id AND a1.attr_type=1
    LEFT JOIN attr a2 ON ticket.ticket_id=a2.ticket_id AND a2.attr_type=2
    LEFT JOIN attr a3 ON ticket.ticket_id=a3.ticket_id AND a3.attr_type=3

Voici un exemple: SQL Fiddle .

53
András Ottó

Bien que vous puissiez utiliser des jointures gauches aliasées, dans ce cas, vous pouvez également utiliser une combinaison d'expressions de regroupement et conditionnelles:

select t.ticket_id,
       max(case when a.attr_type=1 then a.attr_val end) attr_val1,
       max(case when a.attr_type=2 then a.attr_val end) attr_val2,
       max(case when a.attr_type=3 then a.attr_val end) attr_val3
from ticket t
left join attr a on t.ticket_id = a.ticket_id
group by t.ticket_id
9
user359040

Vous utilisez des alias de table

par exemple:

Select 
    ticket.ticket_id,  
    a1.attr_val as attr_val1,
    a2.attr_val as attr_val2,
    a3.attr_val as attr_val3
from ticket
    left join (select * from attr where attr_type=1) a1 on ticket.ticket_id=a1.ticket_id
    left join (select * from attr where attr_type=2) a2 on ticket.ticket_id=a2.ticket_id
    left join (select * from attr where attr_type=3) a3 on ticket.ticket_id=a3.ticket_id
6
podiluska