😎

データサイエンス100本ノック(SQL)91~100

2021/12/02に公開

追記
最近になってGCPのBigQueryでも回答を作ってみたので合わせてそのコードも記載する
基本的にPostgreSQLの下にGCPのコードを記していく


--S-091は解答を見ても良く分からなかったので割愛する
S-091: 顧客テーブル(customer)の各顧客に対し、売上実績のある顧客数と売上実績のない顧客数が1:1となるようにアンダーサンプリングで抽出せよ。


S-092:顧客テーブル(customer)では、
     性別に関する情報が非正規化の状態で保持されている。これを第三正規化せよ。

PostgreSQL
  --genderを除いたテーブルを作成
 drop table if exists customer_nor_3;
 create table if not exists customer_nor_3 as
                                              select customer_id,
                                                     customer_name,
                                                     gender_cd,
                                                     birth_day,
                                                     age,
                                                     postal_cd,
                                                     address,
                                                     application_store_cd,
                                                     application_date,
                                                     status_cd
                                              from customer;

 drop table if exists gender_nor_3;
 create table if not exists gender_nor_3 as
                                            select distinct gender_cd,
                                                            gender
                                            from customer
                                            order by gender_cd asc;

BigQuery
 drop table if exists [データセット名].customer_nor_3;
 create table if not exists [データセット名].customer_nor_3 as
                                                              select customer_id,
                                                                     customer_name,
                                                                     gender_cd,
                                                                     birth_day,
                                                                     age,
                                                                     postal_cd,
                                                                     address,
                                                                     application_store_cd,
                                                                     application_date,
                                                                     status_cd
                                                              from [データセット名].customer;

 drop table if exists [データセット名].gender_nor_3;
 create table if not exists [データセット名].gender_nor_3 as
                                                            select distinct gender_cd,
                                                                            gender
                                                            from [データセット名].customer
                                                            order by gender_cd asc;

参考(第3正規化)
 https://tech.012grp.co.jp/entry/db_normalization
 customerの主キー(Primary Key)は顧客ID(customer_id)である
 {性別コード(gender_cd)} → {性別(gender)} という従属関係が見える。
 {顧客ID(customer_id)} → {性別コード(gender_cd)} という従属関係も明らか。
 つまりは、{顧客ID(customer_id)} → {性別コード(gender_cd)} → {性別(gender)}
 このように段階的な従属関係を、「推移的関数従属」と言う。
 第3正規形の定義:「第2正規形のテーブルから、推移的関数従属している列が切り出されたもの」
 customer(顧客テーブル)をcustomer_nor_3(顧客情報テーブル)とgender_nor_3(性別情報テーブル)に分割する。


S-093:商品テーブル(product)では各カテゴリのコード値だけを保有し、
     カテゴリ名は保有していない。
   カテゴリテーブル(category)と組み合わせて非正規化し、
   カテゴリ名を保有した新たな商品テーブルを作成せよ。

PostgreSQL
 drop table if exists p_c;
 create table if not exists p_c as
                                   select pr.product_cd,
                                          pr.category_major_cd,
                                          ca.category_major_name,
                                          pr.category_medium_cd,
                                          ca.category_medium_name,
                                          pr.category_small_cd,
                                          ca.category_small_name,
                                          pr.unit_price,
                                          pr.unit_cost
                                   from product as pr
                                   left outer join category as ca
                                   on pr.category_small_cd = ca.category_small_cd;

BigQuery
 drop table if exists [データセット名].p_c;
 create table if not exists [データセット名].p_c as
                                                   select pr.product_cd,
                                                          pr.category_major_cd,
                                                          ca.category_major_name,
                                                          pr.category_medium_cd,
                                                          ca.category_medium_name,
                                                           pr.category_small_cd,
                                                          ca.category_small_name,
                                                          pr.unit_price,
                                                          pr.unit_cost
                                                   from [データセット名].product as pr
                                                   left outer join [データセット名].category as ca
                                                   on pr.category_small_cd = ca.category_small_cd
                                                   order by pr.product_cd asc;

S-094:先に作成したカテゴリ名付き商品データを以下の仕様でファイル出力せよ。
    出力先のパスは'/tmp/data'を指定することでJupyterの/'work/data'と共有されるようになっている。
    なお、COPYコマンドの権限は付与済みである。

       ファイル形式はCSV(カンマ区切り)
       ヘッダ有り
       文字コードはUTF-8
PostgreSQL
copy product to 'product_utf-8.csv' with csv delimiter ',' encoding 'utf-8' header;

gcpのBigQueryではGUIで行う事ができる
ただし、料金がかかるかもしれないのでこれ以降は行わない(ストレージ保存に料金がかかるらしい?)


S-095:先に作成したカテゴリ名付き商品データを以下の仕様でファイル出力せよ。
    出力先のパスは'/tmp/data'を指定することでJupyterの/'work/data'と共有されるようになっている。
    なお、COPYコマンドの権限は付与済みである。

     ファイル形式はCSV(カンマ区切り)
     ヘッダ有り
     文字コードはSJIS */
PostgreSQL
copy product to 'product_sjis.csv' with csv delimiter ',' encoding 'sjis' header;

S-096: 先に作成したカテゴリ名付き商品データを以下の仕様でファイル出力せよ。
出力先のパスは'/tmp/data'を指定することでJupyterの/'work/data'と共有されるようになっている。
なお、COPYコマンドの権限は付与済みである。

     ファイル形式はCSV(カンマ区切り)
     ヘッダ無し
     文字コードはUTF-8
PostgreSQL
copy product to 'product_utf-8_no_header.csv' with csv delimiter ',' encoding 'utf-8';

S-097: 先に作成した以下形式のファイルを読み込み、テーブルを作成せよ。
また、先頭3件を表示させ、正しくとりまれていることを確認せよ。

     ファイル形式はCSV(カンマ区切り)
     ヘッダ有り
     文字コードはUTF-8
PostgreSQL
drop table if exists product_utf_8;

create table product_utf_8 (product_cd text,
                            category_major_cd text,
                            category_major_name text,
                            category_medium_cd text,
                            category_medium_name text,
                            category_small_cd text,
                            category_small_name text,
                            unit_price int,
                            unit_cost int);

copy product_utf_8 from 'product_full_utf-8.csv' with csv header;
select * from product_utf_8 limit 3;

S-098:先に作成した以下形式のファイルを読み込み、テーブルを作成せよ。
    また、先頭3件を表示させ、正しくとりまれていることを確認せよ。

     ファイル形式はCSV(カンマ区切り)
     ヘッダ無し
     文字コードはUTF-8
PostgreSQL
drop table if exists product_utf_8_no_header;

create table product_utf_8_no_header (product_cd text,
                                           category_major_cd text,
                                           category_major_name text,
                                           category_medium_cd text,
                                           category_medium_name text,
                                           category_small_cd text,
                                           category_small_name text,
                                           unit_price int,
                                           unit_cost int);

copy product_utf_8_no_header from 'product_full_utf-8_no_header.csv' with csv;
select * from product_utf_8_no_header limit 3;

S-099:先に作成したカテゴリ名付き商品データを以下の仕様でファイル出力せよ。
    出力先のパスは'/tmp/data'を指定することでJupyterの/'work/data'と共有されるようになっている。
    なお、COPYコマンドの権限は付与済みである。

     ファイル形式はTSV(タブ区切り)
     ヘッダ有り
     文字コードはUTF-8 */
PostgreSQL
copy product to 'product_utf-8.tsv' with csv delimiter e'\t' encoding 'utf-8' header;

S-100:先に作成した以下形式のファイルを読み込み、テーブルを作成せよ。
    また、先頭10件を表示させ、正しくとりまれていることを確認せよ。

     ファイル形式はTSV(タブ区切り)
     ヘッダ有り
     文字コードはUTF-8
PostgreSQL
drop table if exists product_utf_8_tsv;

create table product_utf_8_tsv (product_cd text,
                                category_major_cd text,
                                category_major_name text,
                                category_medium_cd text,
                                category_medium_name text,
                                category_small_cd text,
                                category_small_name text,
                                unit_price int,
                                unit_cost int);

copy product_full_utf_8_tsv from 'product_utf-8.tsv' with csv delimiter e'\t' header;
select * from product_utf_8_tsv limit 10;

Discussion