2017-02-27 1 views
0

je suit tables dans MySQLscission de chaîne d'identifiants et concat avec des noms dans MySQL

Tableau 1:
c1 ids
A1 3 | 5 | 2
A2 1 | 2
A3 3
A4 1 | 2 | 3 | 4 | 5
A5 2 | 4 | 1 | 3

Tableau 2:

nom identifiant 1 AA
2 ABERT
3 CDE
4 XXWQ
5 Y

Je veux joindre les deux tables sur tb1.ids = tb2.id comme Split tous les id du tableau 1, puis remplacez-les par leur nom et puis concaténer à nouveau.

sortie

3 | 5 | 2 -> CDE | Y | ABERT
1 | 2 -> AA | ABERT

J'utilise le code suivant pour diviser la chaîne.

CASE WHEN tb1.ids LIKE '%|%'THEN SUBSTRING_INDEX(`tb1.ids` , '|', 1) ELSE tb1.ids END AS id1, 
CASE WHEN tb1.ids LIKE '%|%|%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX(`tb1.ids` , '|', 2),'|',-1) WHEN tb1.ids LIKE '%|%' THEN SUBSTRING_INDEX(`tb1.ids` , '|', -1)ELSE '' END AS id2, 
CASE WHEN tb1.ids LIKE '%|%|%|%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX(`tb1.ids` , '|', 3),'|',-1) WHEN tb1.ids LIKE '%|%|%' THEN SUBSTRING_INDEX(`tb1.ids` , '|', -1) ELSE '' END AS id3, 
CASE WHEN tb1.ids LIKE '%|%|%|%|%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX(`tb1.ids` , '|', 4),'|',-1) WHEN tb1.ids LIKE '%|%|%|%' THEN SUBSTRING_INDEX(`tb1.ids` , '|', -1) ELSE '' END AS id4, 
CASE WHEN tb1.ids LIKE '%|%|%|%|%|%' THEN SUBSTRING_INDEX(SUBSTRING_INDEX(`tb1.ids` , '|', 5),'|',-1) WHEN tb1.ids LIKE '%|%|%|%|%' THEN SUBSTRING_INDEX(`tb1.ids` , '|', -1) ELSE '' END AS id5 
+1

Ne jamais stocker plusieurs valeurs dans une seule colonne. Si vous le faites, vous avez des problèmes comme celui-ci. Pouvez-vous changer votre design de table? –

+0

Je n'ai pas d'accès en écriture à cette base de données. En fait, cette colonne est un itinéraire de plusieurs destinations d'un voyage particulier. –

Répondre

1

Stockage des champs délimités dans une table est presque toujours une mauvaise idée. Toutefois, si le champ est délimité par des virgules, vous pouvez utiliser la fonction FIND_IN_SET. Si vous êtes désespéré, vous pouvez utiliser REPLACE pour changer les délimiteurs en virgules dans la fonction FIND_IN_SET: -

SELECT a.c1, 
     a.ids, 
     GROUP_CONCAT(b.name SEPARATOR '|') 
FROM Table1 a 
INNER JOIN Table2 b 
ON FIND_IN_SET(b.id, REPLACE(a.ids, '|', ',')) 
GROUP BY a.c1, 
     a.ids 
+0

C'est encore mieux que ma solution. –

+0

Merci, et merci d'avoir corrigé les fautes de frappe avec les virgules. – Kickstart

+0

Merci beaucoup, tous les deux :) –

1

Si vous ne pouvez pas changer le schéma que vous pouvez rejoindre en utilisant LIKE et combiner les noms avec GROUP_CONCAT:

select t1.c1, t1.ids, group_concat(t2.name separator '|') as names 
from table1 t1 
join table2 t2 
    on concat('|', t1.ids, '|') like concat('%|', t2.id, '|%') 
group by t1.c1, t1.ids 

Résultat:

╔════╦═══════════╦═════════════════════╗ 
║ c1 ║ ids ║  names  ║ 
╠════╬═══════════╬═════════════════════╣ 
║ A1 ║ 3|5|2  ║ CDE|ABERT|Y   ║ 
║ A2 ║ 1|2  ║ ABERT|AA   ║ 
║ A3 ║ 3   ║ CDE     ║ 
║ A4 ║ 1|2|3|4|5 ║ CDE|Y|ABERT|AA|XXWQ ║ 
║ A5 ║ 2|4|1|3 ║ XXWQ|CDE|ABERT|AA ║ 
╚════╩═══════════╩═════════════════════╝ 

Démo: http://rextester.com/XHUP28245

Si vous avez besoin des noms à commander selon t1.ids, un possible w ay est d'utiliser la fonction Locate pour ORDER BY dans GROUP_CONCAT:

select t1.c1, t1.ids, group_concat(
    t2.name 
    order by locate(concat('|', t2.id, '|'), concat('|', t1.ids, '|')) 
    separator '|' 
) as names 
from table1 t1 
join table2 t2 
    on concat('|', t1.ids, '|') like concat('%|', t2.id, '|%') 
group by t1.c1, t1.ids 

Résultat:

╔════╦═══════════╦═════════════════════╗ 
║ c1 ║ ids ║  names  ║ 
╠════╬═══════════╬═════════════════════╣ 
║ A1 ║ 3|5|2  ║ CDE|Y|ABERT   ║ 
║ A2 ║ 1|2  ║ AA|ABERT   ║ 
║ A3 ║ 3   ║ CDE     ║ 
║ A4 ║ 1|2|3|4|5 ║ AA|ABERT|CDE|XXWQ|Y ║ 
║ A5 ║ 2|4|1|3 ║ ABERT|XXWQ|AA|CDE ║ 
╚════╩═══════════╩═════════════════════╝ 

Démo: http://rextester.com/WIUQ61685

+0

Pourquoi utilisez-vous group by comme si deux valeurs sont identiques alors un seul enregistrement sera créé comme dans A1 -> 3 | 2 | 5 A2 -> 3 | 2 | 5 –

+0

J'ai changé la requête en Quelque chose qui a plus de sens. Vous n'avez pas indiqué le format de sortie exact dans votre question. –

+0

Pourquoi deux mêmes tb2.ids donnent des noms brouillés comme dans A1 -> 3 | 5 | 2 -> CDE | Y | ABERT A2 -> 3 | 5 | 2 -> Y | CDE | ABER –