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

Flet to kolonner, flere rækker ignorerer dubletter - MySQL

Du kunne gøre det med dette udsagn (nej, det ser ikke pænt ud), forudsat at navnet på din tabel er example :

UPDATE
    example e1
SET
    e1.type_a = (
        SELECT
            CONCAT('*', GROUP_CONCAT(DISTINCT n1.value ORDER BY n1.value SEPARATOR '*'), '*') as type_a
        FROM ( 
            SELECT
                id, 
            CASE 
                WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1) = '' THEN NULL
                ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)
            END value
            FROM example e CROSS JOIN (
                SELECT 
                    a.N + b.N * 10 + 1 AS n
                FROM
                    (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
                   ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
                ORDER BY n
            ) n
            WHERE 
                n.n <= 1 + (LENGTH(e.type_a) - LENGTH(REPLACE(e.type_a, '*', '')))
            UNION
            SELECT
                id, 
            CASE 
                WHEN SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_b), '*', n.n), '*', -1) = '' THEN NULL
                ELSE SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_b), '*', n.n), '*', -1)
            END value
            FROM example e CROSS JOIN (
                SELECT 
                    a.N + b.N * 10 + 1 AS n
                FROM
                    (SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) a
                   ,(SELECT 0 AS N UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9) b
                ORDER BY n
            ) n
            WHERE 
                n.n <= 1 + (LENGTH(e.type_b) - LENGTH(REPLACE(e.type_b, '*', '')))
        ) n1
        WHERE 
            n1.id = e1.id
        GROUP BY 
            id
    ),
    e1.type_b = ''
;

Demo af SELECT-sætningen

Forklaring

Grundlæggende tilpassede jeg metoden af peterm for at få splittet gjort. Jeg var nødt til at fjerne den ydre * først af TRIM.

For at tillade den tomme streng som kolonneværdi, har jeg tilføjet CASE-konstruktionen for at eliminere sådanne værdier. Hvis din kolonne har NULL-værdier i stedet, kan du erstatte CASE med

SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)

og

SUBSTRING_INDEX(SUBSTRING_INDEX(TRIM(BOTH '*' FROM e.type_a), '*', n.n), '*', -1)

UNION (uden nøgleordet ALL) i denne konstruktion vil give os listen over forskellige farveværdier, og med GROUP BY id og GROUP_CONCAT får vi den * adskilte værdiliste. Til sidst tilføjer vi en førende og en efterfølgende * for at matche dine krav.

Til opdateringen skal du ændre select, så den kun returnerer én kolonne med én række (med where-sætningen).

Bemærk

Som angivet af peterm vil dette tillade op til 100 værdier i din værdiliste. Jeg tror ikke, du får brug for mere, men hvis du vil, så er du nødt til at tilpasse genereringen af ​​tallene til dine behov.




  1. Forespørg SUM for to felter i to forskellige tabeller

  2. 1045, Adgang nægtet for brugeren 'brugernavn'@'NOT-local' (ved hjælp af adgangskode:JA)

  3. Kør 2 sql-forespørgsler med 1 forespørgsel for at gemme forespørgselsresultatet som .csv-format

  4. IGNORE_DUP_KEY langsommere på klyngede indekser