SQLServerで郵便番号ファイルを使えるようにしよう #1

つづき

https://qiita.com/Inada_Tomonori/items/e387640ca8bae2941d5e


## はじめに

この記事（および続きの記事）は、稲田が作業している状況を記録するログとしての役割と、読者の方に問題点や稲田はこうしたいとの要望を伝えることで解決方法を教えてほしいとの考えで作成しています。
ですので、記事のなかで結果や解決方法が記載されていないなどすっきりしない記事になる可能性があります。
読まれる方は予め了承いただきますようお願いいたします。


## 何がしたいのか

郵便番号を取扱いと考えたとき、通常の手順は

郵便局からデータをダウンロード
　　↓
データベースに展開
　　↓
アプリで利用
　　
となると思います。

参考：

https://www.post.japanpost.jp/zipcode/download.html

ですが、実はこの郵便局からダウンロードしたデータは、（下記のとおり）そのままデータベースに展開するには問題がある状態になってい（ると私は思って）ます。

この記事（および続く記事）の（現段階での）目的は、地名検索や地名から郵便番号を検索する際にデータベースとして利用することです。
また、（現段階での）目標は、ダウンロードで入手したデータをSQLServer上で加工してテーブルに保存し、SQLクエリで呼び出して利用する形にすることです。


## 郵便番号データとはどんなもの？
郵便番号データ（の形式）とは次のようなものです。
郵便局のHPから引用します。

> **郵便番号データファイルの形式等**
> ・全角となっている町域部分の文字数が38文字を越える場合、また半角となっているフリガナ部分の文字数が76文字を越える場合は、複数レコードに分割しています。
> ・この郵便番号データファイルでは、以下の順に配列しています。
>   1)全国地方公共団体コード（JIS X0401、X0402）………　半角数字
>   2)（旧）郵便番号（5桁）………………………………………　半角数字
>   3)郵便番号（7桁）………………………………………　半角数字
>   4)都道府県名　…………　半角カタカナ（コード順に掲載）　（※1）
>   5)市区町村名　…………　半角カタカナ（コード順に掲載）　（※1）
>   6)町域名　………………　半角カタカナ（五十音順に掲載）　（※1）
>   7)都道府県名　…………　漢字（コード順に掲載）　（※1,2）
>   8)市区町村名　…………　漢字（コード順に掲載）　（※1,2）
>   9)町域名　………………　漢字（五十音順に掲載）　（※1,2）
>   10)一町域が二以上の郵便番号で表される場合の表示　（※3）　（「1」は該当、「0」は該当せず）
>   11)小字毎に番地が起番されている町域の表示　（※4）　（「1」は該当、「0」は該当せず）
>   12)丁目を有する町域の場合の表示　（「1」は該当、「0」は該当せず）
>   13)一つの郵便番号で二以上の町域を表す場合の表示　（※5）　（「1」は該当、「0」は該当せず）
>   14)更新の表示（※6）（「0」は変更なし、「1」は変更あり、「2」廃止（廃止データのみ使用））
>   15)変更理由　（「0」は変更なし、「1」市政・区政・町政・分区・政令指定都市施行、「2」住居表示の実施、「3」区画整理、「4」郵便区調整等、「5」訂正、「6」廃止（廃止データのみ使用））
>   ※1 文字コードには、MS漢字コード（SHIFT JIS）を使用しています。
>   ※2 文字セットとして、JIS X0208-1983を使用し、規定されていない文字はひらがなで表記しています。
>   ※3 「一町域が二以上の郵便番号で表される場合の表示」とは、町域のみでは郵便番号が特定できず、丁目、番地、小字などにより番号が異なる町域のことです。
>   ※4 「小字毎に番地が起番されている町域の表示」とは、郵便番号を設定した町域（大字）が複数の小字を有しており、各小字毎に番地が起番されているため、町域（郵便番号）と番地だけでは住所が特定できない町域のことです。
>   ※5 「一つの郵便番号で二以上の町域を表す場合の表示」とは、一つの郵便番号で複数の町域をまとめて表しており、郵便番号と番地だけでは住所が特定できないことを示すものです。
>   ※6 「変更あり」とは追加および修正により更新されたデータを示すものです。
>   ※7 全角となっている町域名の文字数が38文字を超える場合、また、半角カタカナとなっている町域名のフリガナが76文字を越える場合には、複数レコードに分割しています。
>   
>   **データの格納イメージ**
>   ・各項目は、半角の「,」（カンマ）で区切っており、上記の2）～9）までの項目は「"」（ダブルクォーテーション）で囲んでいます。
>   ・上記4）～9）までは可変長形式であり、空白のない形式です。
>   ・1レコードの区切りは、キャリッジリターン（CR）＋ラインフィード（LF）です。
>   ・9）の項目位置に、「"以下に掲載がない場合"」とは、お探しの町域が見つからない場合にお書きいただく番号であり、町域を特定するものではありませんのでご注意ください。
>   ・9）の項目位置に、「"○○市（または町・村）の次に番地がくる場合"」とは、市区町村名の後ろに町域名がなく、番地がくる住所（例：○○郡△△町1234番地）の場合にお書きいただく番号です。
>   ・9）の項目位置に、「"○○市（または町・村）一円"」とは、町域名がない市区町村の場合にお書きいただく番号です。

引用元：　[郵便番号データの説明 - 日本郵政](https://www.post.japanpost.jp/zipcode/dl/readme.html)

要点をまとめます。
* 郵便番号と対応する地点の都道府県名、市区町村名、町域名をカンマ区切りのテキストファイル（CSVファイル）にしたものです。
* 文字コードはシフトJISと書いています（が、UTF8のものもあります）。
* 町域部分の文字数が全角38文字もしくは半角76文字以上なら複数レコードに分割しています。
* 町域名の項目には「"以下に掲載がない場合"」、「"○○市（または町・村）の次に番地がくる場合"」、「"○○市（または町・村）一円"」のように町域名を指示していない内容になることがある。

また、実際のデータを見ると、次のような点があります。
* 一つの町域が場所によって複数の郵便番号と対応する場合、町域名に括弧書きで番地や小字名などで範囲を指定している。

例　郵便番号602-8368　京都府　京都市上京区　の町域名

> 北町（上の下立売通天神道西入上る、上の下立売通御前西入、上の下立売通御前西入上る、上の下立売通御前西入２丁目、上の下立売通御前西入２筋目、下長者町通御前西入、天神道上の下立売上る、天神道仁和寺街道下る、天神道下立売上る、天神道妙心寺道上る、天神道妙心寺道上る西入、仁和寺街道天神道西入下る、仁和寺街道天神道東入下る、御前通上の下立売上る、御前通上の下立売上る西入、御前通下立売上る、御前通下長者町上る西入、御前通仁和寺街道下る西入、御前通妙心寺道上る西入、御前通西裏上の下立売上る、御前通西裏下立売上る）
> キタマチ

 引用元：　[郵便番号 6028368の検索結果 - 日本郵政](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=6028368)

例　郵便番号891-1275　鹿児島県　鹿児島市　の町域名

> 川上町（３６４９、３６６１、３６６７、３６６７－３、３６６９－４、３６７１、３６７２、３６７３－１、３６７４、３６７４－２、３６７４－８、３６８０－１、３７０１、３７０４、３７２３－３、３７２３－５、４１２５、４１２８、４１２８－３、４１２８－４、４１２８－５、４１３２、４１３２－４、４１３３、４１３３－２、４１３８、４２０３、４２０３－１、４２０９、４２０９－６、４２１１－１、４２１５、４２１５－１、４２１６－３、４２１６－１０、４２１６－１２、４２３６－１、４２３８、４２３８－１、４２３８－２、４２４１、４２４２、４２４２－３、４２４４、４２４４－１、４２４４－３、４２４４－４番地）
> カワカミチョウ(3649、3661、3667、3667-3、3669-4、3671、3672、3673-1、3674、3674-2、3674-8、3680-1、3701、3704、3723-3、3723-5、4125、4128、4128-3、4128-4、4128-5、4132、4132-4、4133、4133-2、4138、4203、4203-1、4209、4209-6、4211-1、4215、4215-1、4216-3、4216-10、4216-12、4236-1、4238、4238-1、4238-2、4241、4242、4242-3、4244、4244-1、4244-3、4244-4バンチ)
 
 引用元：　[郵便番号 8911275の検索結果 - 日本郵政](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=8911275)

* 大きなビルで単体で一つの郵便番号が対応する場合やさらに大きなビルで一つの階層に対して一つの郵便番号が対応する場合、町域がビル名やビル名＋階層の表記になる。


例　郵便番号150-6290　東京都　渋谷区　の町域名

> 桜丘町渋谷サクラステージＳＨＩＢＵＹＡサイドＳＨＩＢＵＹＡタワー（地階・階層不明）
> サクラガオカチョウシブヤサクラステージシブヤサイドシブヤタワー(チカイ・カイソウフメイ)

 引用元：　[郵便番号 1506290の検索結果 - 日本郵政](https://www.post.japanpost.jp/cgi-zip/zipcode.php?zip=1506290)


## 郵便番号データの問題点
では、郵便番号データの問題点とはなんでしょうか。

私の思う問題点は次の点です。

1. 町域名の内容が長い場合に複数レコードに分割されているので、結合が必要である。
1. しかし、複数レコードに分割されていることがデータ上識別されていない。
1. 町域名の内容で直接関係しない「"以下に掲載がない場合"」のような文字列を通常の町域名とは別に扱う必要がある。
1. 「"以下に掲載がない場合"」やビルでの「"階層不明"」などほかのレコードにあたって該当がなかった場合に採用されるレコードの処理が必要である。
1. 地番が「"～"」や「"xx地番以降"」のように範囲で指示されている場合の処理が必要である。
1. 町域名には条件を付ける場合に括弧書きをするが、括弧の種類が「"（"」「"）"」と「"「"」「"」"」の２組があり、2階層になっている。
1. 小字名や地番を列挙する場合に区切が「"、"」と「"・"」の2種類になっている。
1. 条件の指定方法で「"を除く"」のように否定形の形式がある。
1. 条件を表すのではない「"（"」「"）"」が使用されている。（2025年3月時点で「"名駅ミッドランドスクエア（高層棟）"」の１ケースのみ）
1.「"〔"」「"〕"」で括られた文字列の取り扱いが不明である。（2025年3月時点で「"〔東京電力福島第二原子力発電所構内〕"」の１ケースのみ）
1. 「"○○市（または町・村）一円"」の「"一円"」ではなく正式な町域名としての「"一円"」がある（2025年3月時点で「"滋賀県 犬上郡多賀町 一円"」の１ケースのみ）
1. 町域名で「"○○"」に複数の文字が一致するような表記がある。（2025年3月時点で「"愛知県 新城市 富岡（○○屋敷）"」の１ケースのみ）

これらの問題点をデータベース的に解決するのにどのように処理をするのがいいかは、まだ検討中です。

## つづく

問題点を論っただけで力尽きたので、ここまでとします。
次回以降の記事で少しづつ進めていこうと思います。
上記の問題点は、運用方法などで解決可能なものや目的によって問題とはならないものがあり、「使用用途を変更するから問題なし」となることもあります。
読んで頂く方には広い心での対応をお願いします。