Det er ikke job for DB
men det er muligt:
CREATE TABLE tab(id INT, col VARCHAR(100)); INSERT INTO tab(id, col) VALUES (1, 'option[A]sum[A]g3et[B]'), (2, '[Cosi]sum[A]g3et[ZZZZ]'); SELECT DISTINCT *FROM ( SELECT id, RIGHT(val, LENGTH(val) - LOCATE('[', val)) AS val FROM ( SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(t.col, ']', n.n), '] ', -1) SOM Val FRA fanen t CROSS JOIN ( VÆLG a.N + b.N * 10 + 1 n FRA (VÆLG 0 SOM N UNION ALLE VÆLG 1 UNION ALLE VÆLG 2 UNION ALLE VÆLG 3 UNION ALLE VÆLG 4 UNION ALLE VÆLG 5 UNION ALLE VÆLG 6 UNION ALLE VÆLG 7 UNION ALLE VÆLG 8 UNION ALLE VÆLG 9) a ,(VÆLG 0 SOM N UNION ALLE VÆLG 1 UNION ALLE VÆLG 2 UNION ALLE VÆLG 3 UNION ALLE VÆLG 4 UNION ALLE VÆLG 5 UNION ALLE VÆLG 6 UNION ALLE VÆLG 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b ) n WHERE n.n <=1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, ']', ''))) ) sub) sWHERE val <> ''ORDER BY ID;
Bemærk:
Afhængigt af col
maksimal længde, du muligvis skal bruge for at generere flere tal i CROSS JOIN
afsnit. For nu er det op til 100.
Output:
Sådan fungerer det:
- Generer taltabel med
CROSS JOIN
- Opdel streng baseret på
]
som skillemåler HØJRE(val, LENGTH(val) - LOCATE('[', val))
fjern delen op til[
- filtrer tomme poster fra
- Få kun
DISTINCT
værdier
Inderste forespørgsel:
╔════╦══════════╗║ id ║ val ║╠════╬═══════════════ A ║║ 1 ║ sum[A ║║ 1 ║ g3et[B ║║ 1 ║ ║╚════╩══════╝══kode
Anden underforespørgsel:
╔════╦═════╗║ id ║ val ║╠════╬══════════╗║ id ║ val ║╠════╬═════║║ 1 B║║ 1 B║ ║ 1 ║ ║╚════╩═════╝
Og yderste forespørgsel:
╔════╦═════╗║ id ║ val ║╠════╬══════════╗║ id ║ val ║╠════╬══════════╗║ ║ 1 B║║║ ╩═════╝
Så tilføje simple:
HVOR n.n <=1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, ']', ''))) AND t.id =?
EDIT 2:
Du vil parse JSON i MySQL. Som jeg sagde før, parse og få værdi i applikationslaget. Dette svar er kun til demo-/legetøjsformål og vil have meget lav ydeevne.
Hvis du stadig insisterer på SQL-løsning:
SELECT id, val,s.nFROM ( SELECT id, RIGHT(val, LENGTH(val) - LOCATE('[', val)) AS val,n FROM ( SELECT id, SUBSTRING_INDEX(SUBSTRING_INDEX(t) .col, ']', n.n), ']', -1) AS val, n.n FRA (SELECT id, REPLACE(col, '[]','') som col FROM fane) t CROSS JOIN (SELECT e.N * 10000 + d.N * 1000 + c.N * 100 + a.N + b.N * 10 + 1 n FRA (VÆLG 0 SOM N UNION ALLE VÆLG 1 UNION ALLE VÆLG 2 UNION ALLE VÆLG 3 UNION ALLE VÆLG 4 UNION ALLE VÆLG 5 UNION ALLE VÆLG ALLE VÆLG 7 UNION ALLE VÆLG 8 UNION ALLE VÆLG 9) a ,(VÆLG 0 SOM N UNION ALLE VÆLG 1 UNION ALLE VÆLG 2 UNION ALLE VÆLG 3 UNION ALLE VÆLG 4 UNION ALLE VÆLG 5 UNION ALLE VÆLG 6 UNION ALLE VÆLG 7 UNION ALLE VÆLG 8 UNION ALLE VÆLG 9) b ,(VÆLG 0 SOM N UNION ALLE VÆLG 1 UNION ALLE VÆLG 2 UNION ALLE VÆLG 3 UNION ALLE VÆLG 4 UNION ALLE VÆLG 5 UNION ALLE VÆLG 6 UNION ALLE VÆLG 7 UNION ALLE VÆLG 8 UNION ALLE VÆLG 9) c ,(VÆLG 0 SOM N UNION ALLE VÆLG 1 UNION ALLE VÆLG 2 UNION ALLE VÆLG 3 UNION ALLE VÆLG 4 UNION ALLE VÆLG 5 UNION ALLE VÆLG 6 UNION ALLE VÆLG 7 UNION ALLE VÆLG 8 UNION ALLE VÆLG 9) d ,(VÆLG 0 SOM N UNION ALLE VÆLG 1 UNION ALLE VÆLG 2 UNION ALLE VÆLG 3 UNION ALLE VÆLG 4 UNION ALLE VÆLG 5 UNION ALLE VÆLG 6 UNION ALLE VÆLG 7 UNION ALLE VÆLG 8 UNION ALLE VÆLG 9) e ) n HVOR n.n <=1 + (LENGTH(t.col) - LENGTH(REPLACE(t.col, '] ', ''))) ) sub) sWHERE val <> ''GROUP BY id, valHAVING n <> MAX(n)ORDER BY id,n;
Output:
╔═════╦═════════════╦════╗║ id ║║════════════ ═════════╬════╣║ 1 ║ CE31285LV4 ║ 1 ║║ 1 ║ D32E ║ 3 ║║ 1 ║ GTX750 ║ 5 ║║ 1 ║ M256S ║ 7 ║║ 1 ║ H2X1T ║ 9 ║ ║ 1 ║ FMLANE4U4 ║ 11 ║╚═════╩═════════════╩═══-kode
EDIT 3:
CROSS JOIN
og hele underforespørgslen er kun taltabel. Det er alt. Hvis MySQL
har funktion til at generere talrække (såsom generate_series
eller forududfyldt taltabel er der ikke behov for CROSS JOIN
.
Taltabel er nødvendig for SUBSTRING_INDEX
: