Mysql
 sql >> база данни >  >> RDS >> Mysql

Обединяване на две колони, множество реда игнориране на дубликати - MySQL

Можете да го направите с това изявление (не, не изглежда добре), като приемем, че името на вашата таблица е 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 = ''
;

Демо на израза SELECT

Обяснение

По принцип адаптирах метода на peterm за да свършите разделянето. Трябваше да премахна външния * първо от TRIM.

За да разреша празния низ като стойност на колона, добавих конструкцията CASE, за да елиминира такива стойности. Ако вместо това колоната ви има стойности NULL, можете да замените CASE с

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

и

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

UNION (без ключовата дума ALL) на тази конструкция ще ни даде списъка с различни цветови стойности и с GROUP BY id и GROUP_CONCAT ще получим списъка със стойности, разделени с *. Последно добавяме начален и краен * за да отговаря на вашите изисквания.

За актуализацията трябва да модифицирате избора, така че да връща само една колона с един ред (с клаузата where).

Забележка

Както е посочено от peterm, това ще позволи до 100 стойности във вашия списък със стойности. Не вярвам да имате нужда от повече, но ако искате, тогава трябва да адаптирате генерирането на числата според нуждите си.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Получаване на всички резултати с помощта на клауза where

  2. Премахнете Mysql реда след определено време

  3. в рамките на групови сортировки в mysql

  4. Трябва ли едно изброяване в MySQL да НЕ е NULL?

  5. Получаване на разлика между броя на две подзаявки