SQLの基本

# 対象者
ProgateでSQLを学習した方。
情報を整理するためにまとめました。

#念頭に置くべきポイント

```sql
select * from (テーブル名) where (カラム名) = "テスト";
```
- selectで対象としているのはカラム(列)
- whereで対象としているのはレコード(行)

完全に正しい考えではないが、このように整理すると理解が進む。

```sql
# 基本フォーマット。慣れるまではこのフォーマットを使い、下記の流れに沿ってSQL文を書いていく。
select
from (テーブル名)

;
```
下記では情報をまとめるために、サブクエリの箇所までは一行にまとめてます。

# 基本の基本の基本
```sql
select * from goods where name like "%商品A%" order by price desc limit 5;
```
1.goodsテーブルの全てのレコードを対象。
2.nameカラムから「商品A」の文字列を含むものを取得し、そのレコードをpriceカラムを基準に降順で並べる。
3.取得したレコードから、priceが安いトップ５のレコードを取得し、値を返す。
***

- nullにはisを使う(=は使えない) 

```sql
select * from goods where price is null;
```
***
- whereを使い。複数の条件を指定する場合は、「and」[or]を使う。

```sql
where name = "商品A" and created_at <= "2020-02-02";
```

#基本の基本
データ加工(指定カラムの合計値や平均値を出すなど)の流れ。
1.データをwhereで検索し、レコードを取得
2.取得したデータを、集計関数を用いて、selectで処理を実行。
※集計関数は、基本selectで指定してあげる。

```sql
select max(price) from goods where name = "にんじゃわんこ"
```
***
カラム名でグループ化した後、データ加工の流れ。
1.データをgroup byでグループ化。（同じカラム名は同じグループになる）
2.取得したデータを、集計関数を用いて、selectで処理を実行。
3.何のカラムをグループ化したか分かりやすい検索結果(レコード)を出すために、グループ化したカラムも、selectしてもらう。
※group byを使う場合、selectで指定できるのは、group byで指定したカラム名と、集計関数のみ。

※group byを用いると、データをグループ化できる。具体的には、指定したカラムで、完全に同一のデータを持つレコードどうしが同じグループとなる！。

```sql
select sum(price), created_at, updated_at from goods group by created_at, updated_at;
```

```sql
 # ¥年齢毎の人数と、その年齢を取得
select age, count(*) as "年齢毎の人数"
from users
group by age;
;
```

```sql
select sales_records.purchased_at, SUM(items.price) AS "売上額"
from sales_records
join items
on sales_records.item_id = items.id
group by purchased_at
order by purchased_at ASC;
```

```sql
 # 10個以上購入したユーザーIDとユーザー名、購入した商品の数を取得してください
select users.id, users.name, count(*) as "購入数"
from sales_records
join users
on sales_records.user_id = users.id
group by users.id, users.name
having count(*) >= 10;
```

```sql
 # 「グラタン」を購入したユーザーのidと名前を取得してください
select users.id, users.name
from sales_records
join users
on sales_records.user_id = users.id
where sales_records.item_id = (
  select id
  from items
  where name = "グラタン"
);

```

```sql
# グラタンより売上額が高い商品の指定されたデータを取得してください
select items.id, items.name, items.price * count(*) as "売上額"
from sales_records
join items
on sales_records.item_id = items.id
group by items.id, items.name, items.price
having (count(*) * items.price) > (
  select count(*) * items.price
  from sales_records
  join items
  on sales_records.item_id = items.id
  where items.name = "グラタン"
);
```


whereで細かい条件を指定してグループ化したデータ加工する場合の流れ
1.whereで検索しレコードを取得。
2.group byでグループ化。
3.selectで集計関数を使い、検索結果を出力。
4.havingで指定した条件があれば、その条件を元に検索結果を出力。(グループ化された後で実行される)

- where:全データ(レコード)を対象。
- having：group byでグループされたレコードを対象。


```sql
select sum(price),created_at from goods where name = "商品A" group by created_at having sum(price) > 1000
```

#基本
サブクエリは()で囲む。※()の中には;はいらない。
サブクエリが実行された後で、外側のクエリが実行される。

```sql
# 意味が分からなくなるから、先にasで取得したいカラム名を命名する。
select name as "調べたかった商品名"
from goods
where purchased_at > (
  select purchased_at
  from goods
  where price = 1000
)
;
```

外部キーを使って、テーブルを分けるメリット
→データの管理・更新がしやすい
***

joinは複数のテーブルを1つに結合できる。ONで条件を指定して、結合したテーブルは1つのテーブルとして扱うことができる。
→最初にjoinが実行されてから、selectが実行される。

```sql
select *
from users
join blogs
on users.id = blogs.user_id
group by blogs.title
;
```

- joinしたテーブル間で、同じカラム名があれば、「テーブル名.カラム名」で指定してあげる。
- joinは複数回できる。※fromにかかるテーブルがjoinにかかるテーブルの外部キーを持っている必要あり。
- 外部キーがnullのレコードは、joinに反映されない。
→こんな時はleft joinを使う！！！！
from側に、外部キーを持っているテーブルを指定する！

```sql
# 外部キーがnullのレコードも、結合後反映される。
select *
from users
left join blogs
on users.id = blogs.user_id
;
```