Dalam database MySQL InnoDB saya, saya memiliki data kode pos kotor yang ingin saya bersihkan.
Data kode pos bersih adalah ketika saya memiliki semua 5 digit untuk kode pos (mis. "90210").
Tetapi untuk beberapa alasan, saya perhatikan dalam database saya bahwa untuk kode pos yang dimulai dengan "0", 0 telah dihapus.
Jadi " Holtsville, New York " dengan kode pos " 00544
" disimpan dalam database saya sebagai " 544
"
dan
" Dedham, MA " dengan kode pos " 02026
" disimpan dalam database saya sebagai " 2026
".
SQL apa yang dapat saya jalankan ke panel depan "0" ke kode pos yang panjangnya tidak 5 digit? Artinya, jika kode pos panjangnya 3 digit, pad depan "00". Jika kode pos terdiri dari 4 digit, pad depan hanya "0".
UPDATE :
Saya baru saja mengubah kode pos menjadi tipe data VARCHAR (5)
sumber
Jawaban:
Simpan kode pos Anda sebagai CHAR (5) alih-alih tipe numerik, atau minta aplikasi Anda membungkusnya dengan nol saat Anda memuatnya dari DB. Cara melakukannya dengan PHP menggunakan
sprintf()
:Atau Anda bisa memiliki MySQL pad untuk Anda dengan
LPAD()
:SELECT LPAD(zip, 5, '0') as zipcode FROM table;
Berikut cara untuk memperbarui dan mengisi semua baris:
ALTER TABLE `table` CHANGE `zip` `zip` CHAR(5); #changes type UPDATE table SET `zip`=LPAD(`zip`, 5, '0'); #pads everything
sumber
ZEROFILL
jawaban.CHARACTER SET
adalah utf8, ituCHAR(5)
akan memakan waktu 15 byte!Anda perlu menentukan panjang kode pos (yang menurut saya harus terdiri dari 5 karakter). Maka Anda perlu memberi tahu MySQL untuk mengisi nol angka.
Misalkan tabel Anda dipanggil
mytable
dan bidang yang dimaksud adalahzipcode
, ketiksmallint
. Anda perlu mengeluarkan pertanyaan berikut:ALTER TABLE mytable CHANGE `zipcode` `zipcode` MEDIUMINT( 5 ) UNSIGNED ZEROFILL NOT NULL;
Keuntungan dari metode ini adalah ia membiarkan data Anda tetap utuh, tidak perlu menggunakan pemicu selama penyisipan / pembaruan data, tidak perlu menggunakan fungsi saat Anda
SELECT
memasukkan data dan Anda selalu dapat menghapus nol ekstra atau menambah panjang bidang. Anda berubah pikiran.sumber
Oke, jadi Anda telah mengalihkan kolom dari Angka ke VARCHAR (5). Sekarang Anda perlu memperbarui bidang kode pos menjadi bantalan kiri. SQL untuk melakukannya adalah:
UPDATE MyTable SET ZipCode = LPAD( ZipCode, 5, '0' );
Ini akan menambah semua nilai di kolom Kode Pos menjadi 5 karakter, menambahkan '0 di sebelah kiri.
Tentu saja, sekarang setelah semua data lama Anda diperbaiki, Anda perlu memastikan bahwa data baru Anda juga tidak memiliki bantalan. Ada beberapa aliran pemikiran tentang cara yang benar untuk melakukan itu:
Tangani dalam logika bisnis aplikasi. Keuntungan: solusi database-independent, tidak melibatkan mempelajari lebih lanjut tentang database. Kekurangan: perlu ditangani di mana saja yang menulis ke database, di semua aplikasi.
Tangani dengan prosedur tersimpan. Keuntungan: Prosedur tersimpan memberlakukan aturan bisnis untuk semua klien. Kekurangan: Prosedur tersimpan lebih rumit daripada pernyataan INSERT / UPDATE sederhana, dan tidak portabel di seluruh database. INSERT / UPDATE kosong masih dapat memasukkan data non-zero-padded.
Tangani dengan pemicu. Keuntungan: Akan berfungsi untuk Prosedur Tersimpan dan pernyataan INSERT / UPDATE kosong. Kekurangan: Solusi portabel paling sedikit. Solusi paling lambat. Pemicu mungkin sulit dilakukan dengan benar.
Dalam hal ini, saya akan menanganinya di level aplikasi (jika ada), dan bukan level database. Lagipula, tidak semua negara menggunakan Kode Pos 5 digit (bahkan tidak di AS - kode pos kami sebenarnya adalah Zip + 4 + 2: nnnnn-nnnn-nn) dan beberapa mengizinkan huruf serta angka. Lebih baik TIDAK mencoba dan memaksa format data dan menerima kesalahan data sesekali, daripada mencegah seseorang memasukkan nilai yang benar, meskipun formatnya tidak seperti yang Anda harapkan.
sumber
Saya tahu ini baik setelah OP. Salah satu cara Anda dapat melakukannya dengan membuat tabel menyimpan data kode pos sebagai INT yang tidak ditandatangani tetapi ditampilkan dengan nol adalah sebagai berikut.
select LPAD(cast(zipcode_int as char), 5, '0') as zipcode from table;
Meskipun ini mempertahankan data asli sebagai INT dan dapat menghemat ruang di penyimpanan, Anda akan meminta server melakukan konversi INT ke CHAR untuk Anda. Ini dapat dilemparkan ke tampilan dan orang yang membutuhkan data ini dapat diarahkan ke sana vs tabel itu sendiri.
sumber
Akan tetap masuk akal untuk membuat bidang kode pos Anda sebagai bidang bilangan bulat tak bertanda tangan yang diisi ke nol.
CREATE TABLE xxx ( zipcode INT(5) ZEROFILL UNSIGNED, ... )
Dengan cara itu mysql mengurus padding untuk Anda.
sumber
atau
Yang pertama membutuhkan 5 byte per kode pos.
Yang kedua hanya membutuhkan 3 byte per kode pos. Opsi ZEROFILL diperlukan untuk kode pos dengan nol di depan.
sumber
Anda harus menggunakannya
UNSIGNED ZEROFILL
dalam struktur tabel Anda.sumber
LPAD bekerja dengan VARCHAR2 karena tidak memberikan spasi untuk byte yang tersisa. LPAD mengubah byte sisa / null menjadi nol pada tipe data LHS SO harus VARCHAR2
sumber