Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Bagaimana cara mengganti setiap instance lain dari karakter tertentu dalam string MySQL?

Anda harus mempertimbangkan untuk menyimpan data Anda dalam skema yang dinormalisasi. Dalam kasus Anda, tabel akan terlihat seperti:

| id | k |        v |
|----|---|----------|
|  1 | A |       10 |
|  1 | B |       20 |
|  1 | C |       30 |
|  2 | A | Positive |
|  2 | B | Negative |

Skema ini lebih fleksibel dan Anda akan tahu alasannya.

Jadi bagaimana cara mengubah data yang diberikan ke dalam skema baru? Anda akan membutuhkan tabel pembantu yang berisi nomor urut. Karena kolom Anda adalah varchar(255) anda hanya dapat menyimpan 128 nilai (+ 127 pembatas) di dalamnya. Tapi mari kita buat 1000 angka saja. Anda dapat menggunakan tabel apa pun dengan baris yang cukup. Tetapi karena setiap server MySQL memiliki information_schema.columns tabel, saya akan menggunakannya.

drop table if exists helper_sequence;
create table helper_sequence (i int auto_increment primary key)
    select null as i
    from information_schema.columns c1
    join information_schema.columns c2
    limit 1000;

Kami akan menggunakan angka ini sebagai posisi nilai dalam string Anda dengan menggabungkan dua tabel.

Untuk mengekstrak nilai dari string yang dibatasi, Anda dapat menggunakan substring_index() fungsi. Nilai pada posisi i akan menjadi

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

Dalam string Anda, Anda memiliki urutan kunci yang diikuti oleh nilainya. Posisi kunci adalah bilangan ganjil. Jadi jika posisi kuncinya adalah i , posisi nilai yang sesuai adalah i+1

Untuk mendapatkan jumlah pembatas dalam string dan membatasi gabungan kita, kita dapat menggunakan

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

Kueri untuk menyimpan data dalam bentuk yang dinormalisasi adalah:

create table normalized_table
    select t.id
        , substring_index(substring_index(t.options, '|', i  ), '|', -1) as k
        , substring_index(substring_index(t.options, '|', i+1), '|', -1) as v
    from old_table t
    join helper_sequence s
      on s.i <= char_length(t.options) - char_length(replace(t.options, '|', ''))
    where s.i % 2 = 1

Sekarang jalankan select * from normalized_table dan Anda akan mendapatkan ini:

| id | k |        v |
|----|---|----------|
|  1 | A |       10 |
|  1 | B |       20 |
|  1 | C |       30 |
|  2 | A | Positive |
|  2 | B | Negative |

Jadi mengapa format ini merupakan pilihan yang lebih baik? Selain banyak alasan lain, salah satunya adalah Anda dapat dengan mudah mengonversinya ke skema lama Anda dengan

select id, group_concat(concat(k, '|', v) order by k separator '|') as options
from normalized_table
group by id;

| id |               options |
|----|-----------------------|
|  1 |        A|10|B|20|C|30 |
|  2 | A|Positive|B|Negative |

atau ke format yang Anda inginkan

select id, group_concat(concat(k, '|', v) order by k separator ',') as options
from normalized_table
group by id;

| id |               options |
|----|-----------------------|
|  1 |        A|10,B|20,C|30 |
|  2 | A|Positive,B|Negative |

Jika Anda tidak peduli dengan normalisasi dan hanya ingin tugas ini selesai, Anda dapat memperbarui tabel Anda dengan

update old_table o
join (
    select id, group_concat(concat(k, '|', v) order by k separator ',') as options
    from normalized_table
    group by id
) n using (id)
set o.options = n.options;

Dan lepaskan normalized_table .

Namun, Anda tidak akan dapat menggunakan kueri sederhana seperti

select *
from normalized_table
where k = 'A'

Lihat demo di 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. Tidak dapat memposting teks ke MySQL menggunakan Insert Into

  2. Apakah tidak masuk akal untuk menetapkan database MySQL untuk setiap pengguna di situs saya?

  3. Mengurutkan berdasarkan beberapa kolom dan juga dengan Rand() di MySQL

  4. Array pengambilan MySQL menambahkan nilai duplikat?

  5. Bagaimana cara masuk otomatis di MySQL dari skrip Shell?