MySQL - "0" ile posta kodunun önüne nasıl geçilir?


93

MySQL InnoDB veritabanımda, temizlemek istediğim kirli posta kodu verilerim var.

Temiz posta kodu verileri, bir posta kodu için 5 hanenin tamamına sahip olduğum zamandır (örneğin, "90210").

Ama bazı nedenlerden dolayı, veritabanımda "0" ile başlayan posta kodları için 0'ın düştüğünü fark ettim.

Yani " Holtsville, New York posta kodu ile" " 00544" olarak benim veritabanında saklanır " 544"

ve

Posta kodlu " Dedham, MA " 02026veritabanımda " " olarak saklanıyor 2026.

5 basamak uzunluğunda olmayan herhangi bir posta kodu için "0" ön pedine hangi SQL'i çalıştırabilirim? Anlamı, posta kodu 3 hane uzunluğundaysa, ön ped "00". Posta kodu 4 rakam uzunluğundaysa, ön kısım sadece "0".

GÜNCELLEME :

Posta kodunu VARCHAR (5) veri türü olarak değiştirdim


3
Görünüşe göre posta kodu için tablo sütunu Number türünde ve soruna neden oluyor. Bu durumda, karakter verilerini saklamak için veri türünü değiştirmeniz gerekecektir.
Kangkan

1
@Kangkan, haklısın. Veri tipim bir sayıydı. Posta kodunu varchar (5) olarak değiştirdim. Şimdi, "0" ile <5 haneli posta kodlarının ön sayfasına nasıl gidilir?
TeddyR

1
VARCHAR yerine CHAR kullanmak daha iyidir. Tablo büyük (tüm diğer sütunlar sabit yalnızca boyutu olsa da) aldığında bir sürü tarafından sorguları hızlandırmak edeceğiz
quantumSoup

2
Ayrıca, diğer ülkelerden posta kodlarının her zaman 5 karakter olmadığını da göz önünde bulundurun.
Bill Karwin

Yanıtlar:


219

Posta kodlarınızı sayısal bir tür yerine CHAR (5) olarak saklayın veya uygulamanızın onu DB'den yüklediğinizde sıfırlarla doldurmasını sağlayın. Bunu PHP ile yapmanın bir yolu sprintf():

echo sprintf("%05d", 205); // prints 00205
echo sprintf("%05d", 1492); // prints 01492

Ya da MySQL'i sizin için aşağıdakilerle doldurabilirsiniz LPAD():

SELECT LPAD(zip, 5, '0') as zipcode FROM table;

İşte tüm satırları güncellemenin ve doldurmanın bir yolu:

ALTER TABLE `table` CHANGE `zip` `zip` CHAR(5); #changes type
UPDATE table SET `zip`=LPAD(`zip`, 5, '0'); #pads everything

Verilerimi veritabanının kendisinde gerçekten temizlemek istiyorum. Bunu SQL ile yapmanın eşdeğerini biliyor musunuz?
TeddyR

1
"UPDATE tablename SET zip = LPAD (zip, 5, '0');" çalışmasını sağlayan aşağıdaki kodu çalıştırdım.
TeddyR

Bu 'kabul edilmiş' cevabın ZEROFILLcevaplar kadar iyi olmadığını iddia ediyorum .
Rick James

Bu cevapta bir kusur. Varsayılan CHARACTER SETutf8 ise, bu CHAR(5)gereksiz yere 15 bayt alır!
Rick James

19

Posta kodunun uzunluğuna karar vermelisiniz (5 karakter uzunluğunda olması gerektiğine inanıyorum). O zaman MySQL'e sayıları sıfır doldurmasını söylemelisiniz.

Diyelim ki tablonuz çağrıldı mytableve söz konusu alan zipcodeyazın smallint. Aşağıdaki sorguyu yapmanız gerekiyor:

ALTER TABLE mytable CHANGE `zipcode` `zipcode`
    MEDIUMINT( 5 ) UNSIGNED ZEROFILL NOT NULL;

Bu yöntemin avantajı, verilerinizi olduğu gibi bırakması, veri ekleme / güncelleme sırasında tetikleyici kullanmaya gerek olmaması SELECT, verileri elde ettiğinizde işlevleri kullanmaya gerek olmaması ve her zaman fazladan sıfırları kaldırabilmeniz veya alan uzunluğunu artırabilmenizdir. fikrini değiştir.


3
Smallint 65535'te maksimuma çıksa da, işaretsiz Zerofill gitmenin yoludur. Cali'nin 9xxxx fermuarları var.
brandon-estrella-dev

4
Diğer ülkeler için posta kodlarını desteklemek istiyorsanız, bir tam sayı istemezsiniz. Bazı ülkeler posta kodlarında harf kullanır.
Wodin

12

Tamam, sütunu Sayı'dan VARCHAR (5) olarak değiştirdiniz. Şimdi posta kodu alanını sol-doldurulacak şekilde güncellemeniz gerekiyor. Bunu yapacak SQL şu şekilde olacaktır:

UPDATE MyTable
SET ZipCode = LPAD( ZipCode, 5, '0' );

Bu, ZipCode sütunundaki tüm değerleri 5 karaktere dolduracak ve sola '0'lar ekleyecektir.

Elbette, artık tüm eski verilerinizi düzelttiğinize göre, yeni verilerinizin de sıfır dolgulu olduğundan emin olmanız gerekir. Bunu yapmanın doğru yolu üzerinde birkaç düşünce okulu vardır:

  • Bunu uygulamanın iş mantığında halledin. Avantajlar: Veritabanından bağımsız çözüm, veritabanı hakkında daha fazla bilgi edinmeyi gerektirmez. Dezavantajlar: Veritabanına yazan her yerde, tüm uygulamalarda ele alınması gerekir.

  • Bunu saklı bir yordamla gerçekleştirin. Avantajlar: Saklanan prosedürler, tüm müşteriler için iş kurallarını uygular. Dezavantajlar: Saklanan prosedürler basit INSERT / UPDATE ifadelerinden daha karmaşıktır ve veritabanları arasında taşınabilir değildir. Çıplak bir INSERT / UPDATE, sıfır olmayan dolgulu verileri ekleyebilir.

  • Bir tetikleyici ile halledin. Avantajlar: Depolanan Prosedürler ve çıplak INSERT / UPDATE ifadeleri için çalışacaktır. Dezavantajlar: En az taşınabilir çözüm. En yavaş çözüm. Tetikleyicilerin doğru yapılması zor olabilir.

Bu durumda, veritabanı düzeyinde değil, uygulama düzeyinde (varsa) idare ederdim. Sonuçta, tüm ülkeler 5 haneli bir Posta Kodu kullanmaz (ABD bile değil - posta kodlarımız aslında Zip + 4 + 2: nnnnn-nnnn-nn'dir) ve bazıları harflerin yanı sıra rakamlara da izin verir. Formatı tam olarak beklediğiniz gibi olmasa da birinin doğru değeri girmesini önlemekten ziyade, bir veri formatını denemeyi ve zorlamamayı ve ara sıra meydana gelen veri hatasını kabul etmemeyi daha iyidir.


4

Bunun OP'den sonra olduğunu biliyorum. Bununla gidebileceğiniz bir yol, tabloyu posta kodu verilerini imzasız bir INT olarak saklayan ancak sıfırlarla görüntülenen bir şekilde tutar.

select LPAD(cast(zipcode_int as char), 5, '0') as zipcode from table;

Bu, orijinal verileri INT olarak korurken ve depolamada bir miktar alan tasarrufu sağlayabilirken, sunucunun sizin için INT'den CHAR'a dönüşümünü gerçekleştirmesini sağlayacaksınız. Bu bir görünüme atılabilir ve bu verilere ihtiyaç duyan kişi oraya masanın kendisine göre yönlendirilebilir.


3

Posta kodu alanınızı sıfır dolgulu bir işaretsiz tamsayı alanı olarak oluşturmanız yine de mantıklı olacaktır.

CREATE TABLE xxx ( zipcode INT(5) ZEROFILL UNSIGNED, ... )

Bu şekilde mysql sizin için dolgu işlemlerini halleder.


3
CHAR(5)

veya

MEDIUMINT (5) UNSIGNED ZEROFILL

İlki, posta kodu başına 5 bayt alır.

İkincisi, posta kodu başına yalnızca 3 bayt alır. SIFIRFILL seçeneği, başında sıfır bulunan posta kodları için gereklidir.



0

LPAD, kalan baytlar için boşluk koymadığından VARCHAR2 ile çalışır. LPAD, LHS'de kalan / boş baytları sıfırlara dönüştürür SO veri türü VARCHAR2 olmalıdır

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.