最近初めて使ったPostgreSQLまとめ

#SQL実行環境
-  PostgreSQL 13.4 
- A5:SQL

#SQL実行の順序
SQL文はプログラムみたいに上から実行されていかない。
下の表の順番で実行される。

|順番|　　〜句|　　内容|
|:|---|---|
|1|FROM|テーブル指定|
|2|JOIN|テーブル結合|
|3|WHERE|条件指定|
|4|GROUP BY|グループ化|
|5|SUM(), AVG()など|関数|
|6|HAVING|集計後の絞り込み|
|7|SELECT|検索|
|8|ORDER BY|並び変え|
参考：https://qiita.com/yurina0402/items/78ae1f536b6755d6221a
もっと詳しく：https://qiita.com/k_0120/items/a27ea1fc3b9bddc77fa1
##WHEREとGROUP BY組み合わせ時の順番
```SQL
SELECT 
    bula
    , bulabula
    , bulabulabula
FROM 
    table_bula
--　知らずにWHERE句をGROUP BY句より下に書いたらエラーになった
GROUP BY 
    --グループ化するカラム名
WHERE 
    --なんかの条件
```

SQL実行の順序ではWHERE句が先に実行されると書いたんですが、なぜかエラーになる。
ここはWHERE句をGROUP BY句上に書くのを意識します。

```SQL
WHERE 
    --なんかの条件
GROUP BY 
    --グループ化するカラム名
```

#to_char関数 : Date型を整形された文字列に変換する
```SQL
SELECT 
   '登録日付は ' || to_char(NOW(), 'YYYY-MM-DD') || ' になります' AS full_time_now     
FROM 
    table_bula

--実行結果
--登録日付は 2021-09-29 になります
```

PostgreSQLでは文字列を入れる場合''シングルクオーテーションで囲む。
MySQLでは""ダブルクォーテーションになる。なのでネットで検索するとき、自分のSQL種類を書いて検索する必要がある。ただSQLで検索しない事。
NOW()の代わりにdate型のカラム名を入れて使うイメージです。
参考：https://www.postgresql.jp/docs/9.2/functions-formatting.html
#right関数 : 文字列の末尾からn文字を返えす
```SQL
right('文字列なのだ', 3)
-- 実行結果
-- なのだ
```
これの逆バージョンの関数は left(str text, n int)です。文字列の先頭からn文字を返します。
参考：https://www.postgresql.jp/document/9.3/html/functions-string.html
#CASE式
 SQL文で if/else 構文のような事が存在します！初めはビックリしました。

```SQL
SELECT 
  some_column_name
  , del_flg 
  , CASE WHEN del_flg = false THEN '削除可能'
         ELSE '削除済み'         
    END AS del_flg_str
FROM
    table_bula
```
CASEから初めてENDで式が終わります。式全体がカラムの値に置換されます。
ENDの次にASを付けてカラム名を指定できます。別名を付けない場合はカラム名はCASEになります。
table_bulaにbool型del_flg（削除フラグ）カラムとdel_flg_str（削除フラグ文字列）カラムがあります。
あるデータが削除されたら、削除フラグがtrueになる仕組みです。
del_flg = false 式の判定がtrueの場合 '削除可能' の文字列が値になります。
WHEN　A　THEN　B　英語そのまま意味が通じてわかりやすいです。
del_flg = false 式の判定がfalseの場合はELSEに当たるので '削除済み' になりますね。

複数のWHEN句で色んなパターンも設定できます。まるでswitch文みたいです。

```SQL
SELECT
    tax_rate
    CASE
        WHEN tax_rate = '1%' THEN 0.01
        WHEN tax_rate = '2%' THEN 0.02
        WHEN tax_rate = '3%' THEN 0.03
        ELSE 0 --税率が1%, 2%, 3% の中、どちらでもない場合は値が0（default値）
    END AS tax_double
FROM tax_table;
```
参考：https://www.postgresql.jp/document/7.3/user/functions-conditional.html
      https://qiita.com/sfp_waterwalker/items/acc7f95f6ab5aa5412f3

#FROM句の副問い合わせ

staffs テーブルがありまして、以下のようなSELECT文を流すと

|  id  | name  |  age  | 
|:     |-      |-      |
|   1  |  Bob  |   28  |
|   2  | Taka  |   25  |
|   3  | Tom   |   28  |
|   4  | Robin |   45  |
|   5  | Suzu  |   45  |

```SQL
SELECT
    age
    , count
FROM
    (  --副問い合わせはカッコで初めて閉める
        SELECT
            age
            , COUNT(age) as count 
        FROM
            staffs 
        GROUP BY
            age
    ) AS age_count_table --テーブル名を付けないと怒られる
WHERE
    --なんかの条件
```
実行結果

|  age | count  |
|:|-|
|  45  |   2    |
|  28  |   2    |
|  25  |   1    |

45歳の人が2名で、28歳の人が2名、25歳の人が1名という結果をテーブルに出しています。
副問い合わせの結果がテーブルになってFROM句に入ります。
##どんな時つかえばいいのか？
上の例では副問い合わせのカラムと主問い合わせのカラムが同じなので副問い合わせをやる意味があんまりないです。
age_count_tableのようにSELECT文結果がテーブル扱いになる事は今は使わないかもしれないが、これが必要な場面があります。
SELECT句にCASEで値を決めるカラムがあるとします。
WHERE句にCASE句で決められるカラム名で条件をつけようとしたら、CASE句をENDまですべてもう１度書かないとエラーになったわけです。
ここで副問い合わせを使用して、問い合わせした結果に対してWHERE句条件をつけるのであればCASE句のカラム名だけを使うのができます。WHERE句にCASE句を全部書く必要がなくなります。
###最後に
うまく説明できないんですが、問い合わせ結果に対してWHERE句でうまくいかない場合は副問い合わせを思い出して、解決できるかもしれない事を覚えておきます。
次の記事ではもっとうまく説明できるよう検索します！