Closed1

SQLで数列を扱う

くぶたくくぶたく

はじめに

SQLで数列を扱うにはどうすればいいのか。
SQLとRDBはデータの行に順序がないということは知っているが...
「順序使ってデータの並びに意味を持たせたい!」と感じた時のためにまとめました。
では、早速始めていきます。

連番を作ろう

SQLで連番を作ることを考えてみましょう。

どのように作るか?
ここで一つクイズを考えてください。

問題
00から99までの100この数の中には、0、1、2.....、9の各数字は、それぞれ何個含まれているか?

1桁の数は前ゼロ(ゼロパディング)をつけて「01」「07」のように表記します。
髪には書かず、頭の中だけで考えてみてください。


それではスタート!!!!


....できましたか?
正解は、どの数字も20個。例えば「1」の文字について、一の位と十の位にそれぞれ現れる箇所を数えます。
すると、一の位が1の数が10個、十の位が1の数も10個。「11」はどちらにも含まれますが、この数だけは1を2個含むので、ダブルカウントにはなりません。


■00 〜 99までの数に、各数字は20個現れる

00 01 02 03 04 05 06 07 08 09
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99



何が言いたいかというと、ある数を「文字」としてみた場合、それは各位を構成する数字を組み合わせて作られる集合として把握できる、ということになる。


クイズ終わり!!!!


さて、本題に戻りましょう。
まず、各位の構成要素となる数字を保持する「数字テーブル」を作ります。
これは10行固定の読み取り専用テーブルです。どんな巨大な数も、この10個の数字を組み合わせて作れることは明らかです。

digit(数字)
0
1
2
3
4
5
6
7
8
9



すると、0 〜 99 までの数は、2つのDigits集合の直積を取ることで作れます。
結果の表記上、前ゼロがなくなっていますが、想像で補って読んでください。

select D1.digit + (D2.digit * 10) as seq
from Digit as D1 cross join Digits D2
order by seq;



D1が一の位、D2が十の位を表します。
クロス結合についても少しおさらいします。
クロス結合は2つの集合の要素の「可能なすべての組み合わせ」を得るものになります。

あとは同じ容量でD3、D4....と追加していけば、何桁の数でもお好みで作れます。
また、始点を0ではなく、1から始めたり「542」のような中途半端な数で止めたりしたい場合は
「where句」に条件を追記しましょう。

select D1.digit + (D2.digit * 10) + (D3.digit * 100) as seq
from Digit as D1 cross join Digits as D2 cross join Digits as D3
where D1.digit + (D2.digit * 10) + (D3.digit * 100) between 1 and 542
order by seq;



ちなみに...BigQueryを使用している私ですが、ChatGPTに「連番作って」と言うと簡単なメソッドで作成してくれました...上のやり方もあるんだ...程度に私は押さえておきます。


ChatGPT案

select 
  sequence_number
from
  unnest(generate_array(1, 10)) as sequence_number


続く...

このスクラップは2023/10/10にクローズされました