sql >> Database teknologi >  >> RDS >> Mysql

Udtræk understreng med et specifikt mønster i MySql

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; 

SqlFiddleDemo

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:

  1. Generer taltabel med CROSS JOIN
  2. Opdel streng baseret på ] som skillemåler
  3. HØJRE(val, LENGTH(val) - LOCATE('[', val)) fjern delen op til [
  4. filtrer tomme poster fra
  5. 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; 

SqlFiddleDemo

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 :




  1. MySQL hente seneste rekord for Group

  2. En sammenligning mellem MySQL Clone Plugin og Xtrabackup

  3. COUNT(*) returnerer flere rækker i stedet for kun én

  4. Oversigt over datakomprimering i SQL Server