[SQL] SQLで素数生成 existsとcaseの巻

2016年7月4日月曜日

SQL sqlite

前回はSQLフィボナッチ数列を生成したけど、調子に乗って、SQLで10000までの素数を生成してみた。
with句は整数列の生成のみに利用して、素数判定自体はSQLらしく非手続き的にするとこんな感じ。

prime.sql
with
  prime(p) as (select 3 union all select p + 2 from prime where p < 10000),
  sieve(s) as (select 3 union all select s + 2 from sieve where s + 2 < 100)
select 2 p
union all
select p from prime
        where not exists (select * from sieve where p > s and p % s = 0)
        order by p;
※2は素数であることを利用していることと、偶数はあらかじめ省いているから、ちょっとズルだけど、パフォーマンス的にこうしてみました。

$ sqlite3 <prime.sql
n         
----------
2
3
5
7
11
...(省略)...
9931
9941
9949
9967
9973

あと、ついでにFizzBuzz問題をSQLでやるとこんな。
with
  seq(i) as (select 1 union all select i + 1 from seq where i < 100)
select case when i % 15 = 0 then 'fizzzbuzz'
            when i %  5 = 0 then 'buzz'
            when i %  3 = 0 then 'fizz'
            else                 i
        end fb
  from seq order by i;
$ sqlite3 <fizzbuzz.sql
fb        
----------
1         
2         
fizz      
4         
buzz      
fizz      
7         
8         
fizz      
buzz      
11        
fizz      
13        
14        
fizzzbuzz 
16        
17        
fizz      
...

よし、これでexistsとcaseは完璧だな!(言い過ぎ)