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

Как да заменя всеки друг екземпляр на конкретен символ в MySQL низ?

Трябва да помислите за съхраняване на вашите данни в нормализирана схема. Във вашия случай таблицата трябва да изглежда така:

<предварителен код>| ID | k | v ||----|---|----------|| 1 | A | 10 || 1 | Б | 20 || 1 | C | 30 || 2 | A | Положителен || 2 | Б | Отрицателен |

Тази схема е по-гъвкава и ще видите защо.

И така, как да конвертирате дадените данни в новата схема? Ще ви трябва помощна таблица, съдържаща последователни номера. Тъй като колоната ви е varchar(255) можете да съхранявате само 128 стойности (+ 127 разделителя) в него. Но нека просто създадем 1000 числа. Можете да използвате всяка таблица с достатъчно редове. Но тъй като всеки MySQL сървър има information_schema.columns таблица, ще я използвам.

отпуснете таблицата, ако съществува helper_sequence;създайте таблица helper_sequence (i int auto_increment първичен ключ) изберете null като i от information_schema.columns c1 присъединете information_schema.columns c2 ограничение 1000; 

Ще използваме тези числа като позиция на стойностите във вашия низ, като обединим двете таблици.

За да извлечете стойност от разделен низ, можете да използвате substring_index() функция. Стойността на позиция i ще бъде

substring_index(substring_index(t.options, '|', i ), '|', -1) 

Във вашия низ имате поредица от ключове, последвани от нейните стойности. Позицията на ключа е нечетно число. Така че, ако позицията на ключа е i , позицията на съответната стойност ще бъде i+1

За да получим броя на разделителите в низа и да ограничим нашето присъединяване, можем да използваме

char_length(t.options) - char_length(replace(t.options, '|', '')) 

Заявката за съхраняване на данните в нормализирана форма би била:

създаване на таблица normalized_table изберете t.id , substring_index(substring_index(t.options, '|', i), '|', -1) като k, substring_index(substring_index(t.options, '|' , i+1), '|', -1) като v от old_table t присъединяване към помощна_последователност s на s.i <=char_length(t.options) - char_length(replace(t.options, '|', '')) където s.i % 2 =1 

Сега стартирайте select * от normalized_table и ще получите това:

<предварителен код>| ID | k | v ||----|---|----------|| 1 | A | 10 || 1 | Б | 20 || 1 | C | 30 || 2 | A | Положителен || 2 | Б | Отрицателен |

Така че защо този формат е по-добър избор? Освен много други причини, едната е, че можете лесно да я конвертирате в старата си схема с

изберете идентификатор, group_concat(concat(k, '|', v) подреждане по k разделител '|') като опции от normalized_tablegroup по id;| ID | опции ||----|-----------------------|| 1 | A|10|B|20|C|30 || 2 | A|Положителен|B|Отрицателен | 

или в желания от вас формат

изберете идентификатор, group_concat(concat(k, '|', v) подреждане по k разделител ',') като опции от normalized_tablegroup по id;| ID | опции ||----|-----------------------|| 1 | A|10,B|20,C|30 || 2 | A|Положителен, B|Отрицателен | 

Ако не ви пука за нормализиране и просто искате тази задача да бъде изпълнена, можете да актуализирате таблицата си с

актуализиране на old_table ojoin ( изберете id, group_concat(concat(k, '|', v) подреждане по k разделител ',') като опции от нормализирана_таблица група по идентификатор) n с помощта на (id)set o.options =n.опции; 

И пуснете normalized_table .

Но тогава няма да можете да използвате прости заявки като

изберете *от normalized_table, където k ='A' 

Вижте демото на rextester.com



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Doctrine не запазва обект с булеви стойности и PDO::ATTR_EMULATE_PREPARES =false в Mysql

  2. PHP - uniqid(,true) срещу uniqid()+mt_rand()

  3. Как да архивирам и възстановя MySQL база данни?

  4. Използване на контрол на версиите (Git) на MySQL база данни

  5. Проблем с индексите на MySQL FULLTEXT