inner joinで条件を設定しない時

# inner join で条件を指定しないとどうなるか
inner join句は結合するテーブル同士でどのキーで結合するかを指定する。
指定しなくてもクエリは実行される（実行エラーにならない）が、挙動が変わる。

# テスト用テーブル
#### customers （顧客テーブル）
|  id  |  customer_name  |
| ---- | ---- |
|  1  |  hirata  |
|  2  |  kanazawa  |
|  3  |  fukuda  |

#### products (商品テーブル 名称と金額のみ）
|  id  |  product_name  | price |
| ---- | ---- | ---- |
|  1  |  pencil  | 100 |
|  2  |  eraser  | 120 | 
|  3  |  note  | 150 |


#### order_history (注文履歴、注文数などは省略）
|  id  |  customer_id  | product_id | date |
| ---- | ---- | ---- | ---- |
|  1  |  1  | 1 | 2021-06-07 |
|  2  |  2  | 1 | 2021-06-07 | 
|  3  |  2  | 2 | 2021-06-07 | 
|  4  |  2  | 3 | 2021-06-08 | 
|  5  |  3  | 1 | 2021-06-05 | 
|  6  |  3  | 3 | 2021-06-08 | 

# 基本的な(left) inner join句の書き方
```
-- 注文履歴と商品テーブルと顧客テーブルを結合
select * from order_history o inner join products p on o.product_id = p.id 
```
###result
|o.id|o.customer_id|o.product_id|o.order_date|p.id|p.product_name|p.price|c.id|c.customer_name|
|--|-----------|----------|----------|--|------------|-----|--|-------------|
|1|1|1|2021-06-07|1|pencil|100|1|hirata|
|2|2|1|2021-06-07|1|pencil|100|2|kanazawa|
|3|2|2|2021-06-07|2|eraser|120|2|kanazawa|
|4|2|3|2021-06-08|3|note|150|2|kanazawa|
|5|3|1|2021-06-05|1|pencil|100|3|fukuda|
|6|3|3|2021-06-08|3|note|150|3|fukuda|


注文履歴をベースに、


# 結合条件を指定しない場合
```
select * from order_history o inner join products p inner join customers c;
```
###result
|o.id|o.customer_id|o.product_id|o.order_date|p.id|p.product_name|p.price|c.id|c.customer_name|
|--|-----------|----------|----------|--|------------|-----|--|-------------|
|1|1|1|2021-06-07|1|pencil|100|1|hirata|
|1|1|1|2021-06-07|2|eraser|120|1|hirata|
|1|1|1|2021-06-07|3|note|150|1|hirata|
|1|1|1|2021-06-07|1|pencil|100|2|kanazawa|
|1|1|1|2021-06-07|2|eraser|120|2|kanazawa|
|1|1|1|2021-06-07|3|note|150|2|kanazawa|
|1|1|1|2021-06-07|1|pencil|100|3|fukuda|
|1|1|1|2021-06-07|2|eraser|120|3|fukuda|
|1|1|1|2021-06-07|3|note|150|3|fukuda|
|2|2|1|2021-06-07|1|pencil|100|1|hirata|
|2|2|1|2021-06-07|2|eraser|120|1|hirata|
|2|2|1|2021-06-07|3|note|150|1|hirata|
|2|2|1|2021-06-07|1|pencil|100|2|kanazawa|
|2|2|1|2021-06-07|2|eraser|120|2|kanazawa|
.......

と、結果が大量になるので途中までだが、結合条件を指定しないと全行で結合してしまう。
これはcross join指定をしているのと同じ。

```
select * from order_history o cross join products p cross join customers c
```


# この挙動が便利な時（cross join）

全組み合わせが確認できるので、それなりに便利。
私は、日付ごとに集計結果を出力したい時で、「集計結果にならない日付も出力したい場合」に全ての日付でテーブルを作成する時に使用したりします。
例のorder_historyでは、6月5日、7日、8日のデータがあるため、これで商品の日付ごとを集計すると6日のデータが出力されない。

```
select product_id ,order_date, sum(price) from order_history o inner join products p on p.id = o.product_id group by product_id ,order_date;
```
|product_id|order_date|sum(price)|
|----------|----------|----------|
|1|2021-06-05|100|
|1|2021-06-07|200|
|2|2021-06-07|120|
|3|2021-06-08|300|

cross joinで商品✕日付の全組み合わせを出力しておいて、それに結果を紐付けると結果の無い日付も出力対象になる。

```
select p.id, p.product_name, d, order_date, sum_price from products p cross join
(select
date_format(date_add('2021-06-04', interval td.generate_series day), '%Y-%m-%d') as d
from
(
SELECT 0 generate_series FROM DUAL WHERE (@num:=1-1)*0 UNION ALL
SELECT @num:=@num+1 FROM `information_schema`.COLUMNS LIMIT 7
) as td
) date_table
left join 
(select product_id ,order_date, sum(price) as sum_price from order_history o inner join products p on p.id = o.product_id group by product_id ,order_date) ledger
on ledger.product_id = p.id and ledger.order_date = date_table.d
order by p.id, d
;
```

|id|product_name|d|order_date|sum_price|
|--|------------|-|----------|---------|
|1|pencil|2021-06-05|2021-06-05|100|
|1|pencil|2021-06-06|||
|1|pencil|2021-06-07|2021-06-07|200|
|1|pencil|2021-06-08|||
|1|pencil|2021-06-09|||
|1|pencil|2021-06-10|||
|1|pencil|2021-06-11|||
|2|eraser|2021-06-05|||
|2|eraser|2021-06-06|||
|2|eraser|2021-06-07|2021-06-07|120|
|2|eraser|2021-06-08|||
|2|eraser|2021-06-09|||
|2|eraser|2021-06-10|||
|2|eraser|2021-06-11|||
|3|note|2021-06-05|||
|3|note|2021-06-06|||
|3|note|2021-06-07|||
|3|note|2021-06-08|2021-06-08|300|
|3|note|2021-06-09|||
|3|note|2021-06-10|||
|3|note|2021-06-11|||


MySQL8.0はWindow関数も使えたり集計関数も増えているので、5.7までで無理やりやるとこんな感じというところはありますが。
ともあれ、たまにSQL書こうとすると間違ったりするので注意。