有人可以向我解释一下此SQL查询的工作原理吗?
WITH recursive n(n) AS (
SELECT 2 n
UNION ALL
SELECT n+1 FROM n WHERE n<1000
)
SELECT a.n
FROM n a
LEFT JOIN n b
ON b.n < sqrt(a.n)
GROUP BY a.n
HAVING a.n=2 OR MIN(a.n % b.n) > 0;
这将在PostgresQL中生成以下内容:
n
====
251
887
601
647
577
...
9
(177 rows)
我对逐行细分的理解:
SELECT 2 n
-将数字2选择为n [CTE的锚点成员]
UNION ALL
-与n <1000的递归分量n + 1组合,因此显示2到1000之间的所有数字
SELECT a.n FROM n a
-运行上述查询[CTE的递归成员]
LEFT JOIN n b
-左键将数字2-1000与第二组数字连接起来
ON b.n < sqrt(a.n)
-第二组数字小于第一列数字的平方根吗?
GROUP BY a.n
-仅显示数字的第一列
HAVING a.n=2 OR MIN(a.n. % b.n) > 0
-......其中A = 2或A模B的最小值大于0?
这是一个愚蠢的查询,但是对破译它的任何帮助将不胜感激。
您的查询经过正确修复后,会生成一个低于1000的素数列表:
WITH recursive n(n) AS (
SELECT 2 n
UNION ALL
SELECT n+1 FROM n WHERE n<1000
)
SELECT a.n
FROM n a
LEFT JOIN n b
ON b.n <= sqrt(a.n) -- Fix #1
GROUP BY a.n
HAVING a.n=2 OR a.n=3 OR MIN(a.n % b.n) > 0 -- Fix #2
ORDER BY a.n ASC
解释非常简单:查询的递归部分只是一种为您提供从2(含)到1000(不含)的数字列表的方法。您可以将递归子句替换为填充有连续整数的实际表。
然后将这些数字输入查询的非CTE部分,并根据条件将其结合在一起b.n < sqrt(a.n)
。所述a
侧表示素数候补; 该b
方代表候选人除数。
这是查询中的第一个错误:<
必须更改为<=
,否则素数平方的平方根将包含在输出中。
该GROUP BY
组潜在的素数,其候选人除数放到同一个组。HAVING
子句删除所有带有一个或多个候选因子的候选因子,该因子除以候选素数,即其中MIN(a.n % b.n)
为零。
这是您需要进行第二次修复的地方,因为3
素数的平方根小于2
列表中最小的候选除数。因此,3
最终根本没有候选除数,并被HAVING
子句抛弃。您需要添加OR a.n=3
以保存它。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句