今天是圆周率日!让我们用 SQL 来计算圆周率吧
圆周率日快乐!我们想着用 ClickHouse 的 SQL 查询来计算圆周率应该挺有意思的,以下是我们目前的一些成果……
- 这个示例使用 ClickHouse 的
numbers_mt表函数返回 10 亿行,完成运算仅需 40ms:
SELECT 4 * sum(if(number % 2, -1, 1) / ((number * 2) + 1)) AS pi
FROM numbers_mt(1000000000.)
┌- 下面这个示例同样会处理 10 亿个数字,只是速度稍慢一些:
SELECT 3 + (4 * sum(if((number % 2) = 0, if((number % 4) = 0, -1 / ((number * (number + 1)) * (number + 2)), 1 / ((number * (number + 1)) * (number + 2))), 0))) AS pi
FROM numbers_mt(2, 10000000000)
┌- 显然,这是我们在 ClickHouse 里最喜欢的一种方法 (而且也是最精确的!) :
SELECT pi()
┌- 这题一看就是懂三角函数的人写的:
SELECT 2 * asin(1) AS pi
┌- 这里有一个很实用的 API,可让你指定想要的位数:
SELECT *
FROM url('https://api.pi.delivery/v1/pi?start=0&numberOfDigits=100', 'JSONEachRow')
┌- 这个思路很巧妙 - 它用到了 ClickHouse 的距离函数:
WITH random_points AS
(
SELECT (rand64(1) / pow(2, 64), rand64(2) / pow(2, 64)) AS point
FROM numbers(1000000000)
)
SELECT (4 * countIf(L2Norm(point) < 1)) / count() AS pi
FROM random_points
┌- 如果你是物理学家,你一定会喜欢这个:
SELECT 22 / 7
┌- 另一种间接方法 (由 Alexey Milovidov 提出) 可精确到小数点后 7 位,而且速度很快:
WITH
10 AS length,
(number / 1000000000.) * length AS x
SELECT pow((2 * length) * avg(exp(-(x * x))), 2) AS pi
FROM numbers_mt(1000000000.)
┌