MySQLで適当な件数をSELECT文だけでつくる

既存データを使用しないで、連続した日付を特定の件数分欲しかったので、和集合と直積を使ってみた。
MySQLに、OracleのLEVEL擬似列のような機能があれば、もう少し楽なんだけとなぁ

# やってみた

レコードが拾えることを先ずは確認。
和集合してみて、その後で直積に挑戦。

## 1レコードの場合

```sql:SQL
select 0 as n;
```
```text:実行結果
mysql> select 0 as n;
+---+
| n |
+---+
| 0 |
+---+
1 row in set (0.00 sec)
```

## 和集合（2レコードの場合）

```sql:SQL
select 0 as n union select 1 as n;
```
```text:実行結果
mysql> select 0 as n union select 1 as n;
+---+
| n |
+---+
| 0 |
| 1 |
+---+
2 rows in set (0.00 sec)
```

## 複数の和集合（3レコードの場合）

```sql:SQL
select 0 n union select 1 n union select 2 n;
```
```text:実行結果
mysql> select 0 n union select 1 n union select 2 n;
+---+
| n |
+---+
| 0 |
| 1 |
| 2 |
+---+
3 rows in set (0.00 sec)
```

## 和集合したものを直積

和集合(union)の記述が分かったので、次は直積。

2レコードの直積だと、あまり増えない。
かといって、8レコードだと記述量が多い気がする。
5とか6だと分かりにくそう（個人的に）

連続したデータになるよう、selectの後に設定している数値は、次のように設定。

| | 1列目 | 2列目 | 3列目 | 4列目 |
|:---|:-----------|:-----------|:---------------|:---------------|
| 1行目 | 4 ^ 0 * 0 = 0  | 4 ^ 0 * 1 = 1  | 4 ^ 0 * 2 = 2  | 4 ^ 0 * 3 = 3  |
| 2行目 | 4 ^ 1 * 0 = 0  | 4 ^ 1 * 1 = 4  | 4 ^ 1 * 2 = 8  | 4 ^ 1 * 3 = 12 |
| 3行目 | 4 ^ 2 * 0 = 0  | 4 ^ 2 * 1 = 16 | 4 ^ 2 * 2 = 32 | 4 ^ 2 * 3 = 48 |

```sql:SQL
select
    (v21.n + v22.n + v23.n) n
from
    (select n from (select 0 n union select  1 n union select  2 n union select  3 n) v1) v21,
    (select n from (select 0 n union select  4 n union select  8 n union select 12 n) v1) v22,
    (select n from (select 0 n union select 16 n union select 32 n union select 48 n) v1) v23
;
```
```text:実行結果
mysql> select
    ->     (v21.n + v22.n + v23.n) n
    -> from
    ->     (select n from (select 0 n union select    1 n union select    2 n union select    3 n) v1) v21,
    ->     (select n from (select 0 n union select    4 n union select    8 n union select   12 n) v1) v22,
    ->     (select n from (select 0 n union select   16 n union select   32 n union select   48 n) v1) v23
    -> ;
+----+
| n  |
+----+
|  0 |
|  1 |
|  2 |

～途中省略～

| 62 |
| 63 |
+----+
64 rows in set (0.00 sec)
```
64 レコード ＝ 4レコード ^ 3


後はLIMITかけるなりして、制限かければOK。
連続しているか気になるようであれば、ユーザー定義変数を利用した行番号を使用しても良いかもしれない。


### 連続した日付にする場合

4096 レコード ＝ 4レコード ^ 6

```sql:SQL
select
    date_add('2018-01-01', interval num.n day) as dt
from
    (select (v21.n + v22.n + v23.n + v24.n + v25.n + v26.n) n from
        (select n from (select 0 n union select    1 n union select    2 n union select    3 n) v1) v21,
        (select n from (select 0 n union select    4 n union select    8 n union select   12 n) v1) v22,
        (select n from (select 0 n union select   16 n union select   32 n union select   48 n) v1) v23,
        (select n from (select 0 n union select   64 n union select  128 n union select  192 n) v1) v24,
        (select n from (select 0 n union select  256 n union select  512 n union select  768 n) v1) v25,
        (select n from (select 0 n union select 1024 n union select 2048 n union select 3072 n) v1) v26
    ) num
;
```
```text:実行結果
mysql> select
    ->     date_add('2018-01-01', interval num.n day) as dt
    -> from
    ->     (select (v21.n + v22.n + v23.n + v24.n + v25.n + v26.n) n from
    ->         (select n from (select 0 n union select    1 n union select    2 n union select    3 n) v1) v21,
    ->         (select n from (select 0 n union select    4 n union select    8 n union select   12 n) v1) v22,
    ->         (select n from (select 0 n union select   16 n union select   32 n union select   48 n) v1) v23,
    ->         (select n from (select 0 n union select   64 n union select  128 n union select  192 n) v1) v24,
    ->         (select n from (select 0 n union select  256 n union select  512 n union select  768 n) v1) v25,
    ->         (select n from (select 0 n union select 1024 n union select 2048 n union select 3072 n) v1) v26
    ->     ) num
    -> ;
+------------+
| dt         |
+------------+
| 2018-01-01 |
| 2018-01-02 |
| 2018-01-03 |

～途中省略～

| 2029-03-18 |
| 2029-03-19 |
+------------+
4096 rows in set (0.00 sec)
```