MySQL InnoDBデータベースには、クリーンアップしたい汚い郵便番号データがあります。
きれいな郵便番号データは、郵便番号の5桁すべて(「90210」など)があるときです。
しかし、何らかの理由で、データベースで「0」で始まる郵便番号の場合、0が削除されていることに気付きました。
したがって、「Holtsville、New York "zipcode" 00544
"を使用すると、データベースに" 544
"として保存されます。
そして
"Dedham、MA"郵便番号付き "02026
"は "2026
"としてデータベースに保存されます。
長さ5桁ではない郵便番号のフロントパッド「0」に対して実行できるSQLは何ですか?つまり、郵便番号の長さが3桁の場合、フロントパッドは「00」です。郵便番号の長さが4桁の場合、フロントパッドは「0」だけです。
UPDATE:
Zipcodeをデータ型VARCHAR(5)に変更しました
Zipcodeを数値型ではなくCHAR(5)として保存するか、DBからロードするときにアプリケーションでゼロを埋め込むようにします。 sprintf()
を使用してPHPでそれを行う方法:
echo sprintf("%05d", 205); // prints 00205
echo sprintf("%05d", 1492); // prints 01492
または、MySQLに LPAD()
を埋め込みます:
SELECT LPAD(Zip, 5, '0') as zipcode FROM table;
すべての行を更新してパディングする方法は次のとおりです。
ALTER TABLE `table` CHANGE `Zip` `Zip` CHAR(5); #changes type
UPDATE table SET `Zip`=LPAD(`Zip`, 5, '0'); #pads everything
郵便番号の長さを決定する必要があります(長さは5文字にする必要があります)。次に、数字をゼロで埋めるようにMySQLに指示する必要があります。
テーブルの名前がmytable
で、問題のフィールドがzipcode
であり、smallint
と入力するとします。次のクエリを発行する必要があります。
ALTER TABLE mytable CHANGE `zipcode` `zipcode`
MEDIUMINT( 5 ) UNSIGNED ZEROFILL NOT NULL;
この方法の利点は、データをそのまま残し、データの挿入/更新中にトリガーを使用する必要がないこと、データをSELECT
するときに関数を使用する必要がないこと、および余分なゼロをいつでも削除できることです。気が変わったらフィールド長を増やしてください。
それでは、列をNumberからVARCHAR(5)に切り替えました。ここで、郵便番号フィールドを更新して左詰めにする必要があります。それを行うSQLは次のようになります。
UPDATE MyTable
SET ZipCode = LPAD( ZipCode, 5, '0' );
これにより、ZipCode列のすべての値が5文字に埋め込まれ、左側に「0」が追加されます。
もちろん、古いデータをすべて修正したら、新しいデータにもゼロが埋め込まれていることを確認する必要があります。それを行う正しい方法については、いくつかの考え方があります。
アプリケーションのビジネスロジックで処理します。利点:データベースに依存しないソリューションであり、データベースについてさらに学習する必要はありません。欠点:すべてのアプリケーションで、データベースに書き込むすべての場所で処理する必要があります。
ストアドプロシージャで処理します。利点:ストアドプロシージャは、すべてのクライアントにビジネスルールを適用します。短所:ストアドプロシージャは、単純なINSERT/UPDATEステートメントよりも複雑であり、データベース間で移植性がありません。そのままのINSERT/UPDATEは、ゼロ以外の埋め込みデータを挿入できます。
トリガーで処理します。利点:ストアドプロシージャおよびベアINSERT/UPDATEステートメントで機能します。短所:最小のポータブルソリューション。最も遅いソリューション。トリガーを正しく取得するのは難しい場合があります。
この場合、データベースレベルではなく、アプリケーションレベルで(もしあれば)処理します。結局のところ、すべての国が5桁の郵便番号を使用しているわけではなく(米国さえも-私たちの郵便番号は実際にはZip + 4 + 2:nnnnn-nnnn-nn)、いくつかの文字と数字を許可しています。データ形式が予期したものではない場合でも、誰かが正しい値を入力できないようにするよりも、データ形式を強制して試行せず、時折発生するデータエラーを受け入れない方が良いです。
テーブル構造でUNSIGNED ZEROFILL
を使用する必要があります。
私はこれがOPの後であることを知っています。 zipcodeデータを符号なしINTとして格納するがゼロで表示されるテーブルを保持する方法の1つは、次のとおりです。
select LPAD(cast(zipcode_int as char), 5, '0') as zipcode from table;
これにより、元のデータがINTとして保持され、ストレージのスペースを節約できますが、サーバーにINTからCHARへの変換を実行させることになります。これをビューにスローすることができ、このデータを必要とする人は、テーブル自体ではなくそこに誘導できます。
CHAR(5)
または
MEDIUMINT (5) UNSIGNED ZEROFILL
最初は郵便番号ごとに5バイトかかります。
2番目は、郵便番号ごとに3バイトのみを取ります。 ZEROFILLオプションは、先行ゼロを含む郵便番号に必要です。
郵便番号フィールドをゼロで埋められた符号なし整数フィールドとして作成することは依然として意味があります。
CREATE TABLE xxx ( zipcode INT(5) ZEROFILL UNSIGNED, ... )
そうすれば、mysqlがパディングを処理します。
LPADは、残りのバイトにスペースを入れないため、VARCHAR2で機能します。 LPADは、LHS SOデータ型の残余/ nullバイトをゼロに変更します。VARCHAR2