質問: 1 for i in 1..n retval *= i ``` と簡単に書けると思うのですが MySQL ではどのように書くのが(速度的にもソース的にも)早いでしょうか 1〜N のテーブルを生成してから exp(sum(log(n))) を取るみたいな記事も見かけたのですが log や exp は整数演算に比べたら遥かに重そうなので無駄な気がします こういうのは1度プログラム側にデータを取得してプログラム側で計算するしかないのでしょうか ### 補足: MySQL 5.7 です ### 追記 やりたいことの詳細を書くと 平均と分散カラムを持ってる数万件の正規分布レコードに対して 現在時刻がどの累積分布の位置にあるかを計算して 特定の位置にあるレコードだけを取得するという処理を Lambda で行いたいです wiki の「これを反復的に計算するには、以下のように定式化するのが扱い易い。」の式を使おうと思っています。(SVG なので貼れない) 外側は sum なんですが内側のループが実質階乗なのでどう書けばいいか質問した次第です。 近似式も書いてあるのですが「実軸付近の誤差関数の値について、少なくとも十進で1桁の精度」の意味がよくわからなかったのと、 級数展開でも「最初の方の幾つかの項だけでよい近似が得られ、テイラー展開よりも収束が早い」 とあるので眼福計算を採用しました。 必要な精度は横軸が1日の分布で精度は秒あれば十分なので 1 / 24 x 3600 程度です 近似式の方でもこの精度は満たせるものなのでしょうか? 式自体は複雑ですが上記精度要件から実際は四則演算100回もない程度の軽い処理で、 取得データは毎回数件になるというケースなので、 ネットワークオーバーヘッドを使うより MySQL 側でやる方がメリットが大きいかなと考えました
回答: 階乗を求めるSQLです。試したのは、mysql 8.0.18.0 32bit版です。 metropolisさんのコメントにあるとおり21はエラーとなりました。 SQL === ``` set @n := 20; select f from ( with recursive rc(f, i) as( select 1, @n union all select f * i, i-1 from rc where i-1 >= 0) select f, i from rc ) as a where i = 1 ; ``` 結果 == ``` 2432902008176640000 ``` KTIさんが解決したかったこととは異なる回答であることは承知していますが、 with句を使って再帰のSQLを書くときの参考になるかと考え、回答をする次第です。