vertica生成带数字和表格的表格选择素数

时间:2017-07-09 07:44:06

标签: sql vertica

我正在使用Vertica版本8 +

我需要创建一个数字从1到N的表,并选择素数

我已经完成了在SQLite3中这样做,但Vertica不允许递归WITH

https://forum.vertica.com/discussion/206185/recursive-queries

修改

WITH seq AS (
  SELECT n FROM (
    SELECT ROW_NUMBER() OVER() AS n 
    FROM (
        SELECT 1 
        FROM (
            SELECT date(0) + INTERVAL '1 second' AS i 
            UNION ALL
            SELECT date(0) + INTERVAL '100 seconds' AS i 
        ) _
        TIMESERIES tm AS '1 second' OVER(ORDER BY i)
    ) _ 
  ) _ 
  WHERE n > 1 -- 1 is not prime number
)

SELECT n 
FROM (SELECT n FROM seq) _  
WHERE n NOT IN (
  SELECT n FROM (
    SELECT s1.n AS n, s2.n AS n2
    FROM seq AS s1 
    CROSS JOIN seq AS s2
    ORDER BY n, n2
  ) _
  WHERE n2 < n AND n % n2 = 0
)
ORDER BY n

1 个答案:

答案 0 :(得分:3)

您不需要递归WITH。

第一步。你需要生成从1到N的所有数字(让我们说1000)。您可以使用TIMESERIES在Vertica中轻松完成此操作。以下将生成从1到1000的所有数字:

WITH seq AS (
    SELECT ROW_NUMBER() OVER() AS num FROM (
        SELECT 1 FROM (
            SELECT date(0) + INTERVAL '1 second' AS se UNION ALL
            SELECT date(0) + INTERVAL '1000 seconds' AS se ) a
        TIMESERIES tm AS '1 second' OVER(ORDER BY se)
    ) b
)
SELECT num FROM seq ; 
 num  
------
    1
    2
    3
    4
  ...
  997
  998
  999
 1000

第二步我们只需从上面的结果集中排除非素数数字(请参阅herehere和{{ 3}}):

WITH seq AS (
    SELECT ROW_NUMBER() OVER() AS num FROM (
        SELECT 1 FROM (
            SELECT date(0) + INTERVAL '1 second' AS se UNION ALL
            SELECT date(0) + INTERVAL '1000 seconds' AS se ) a
        TIMESERIES tm AS '1 second' OVER(ORDER BY se)
    ) b
)
SELECT num as prime 
FROM seq
WHERE num NOT IN (
    SELECT s1.num * s2.num
    FROM seq s1 CROSS JOIN seq s2
        WHERE s1.num BETWEEN 2 AND CEILING (SQRT (1000)) 
        AND s1.num <= s2.num
        AND s2.num * s1.num <= 1000
)
ORDER BY 1
;
 prime 
-------
     1
     2
     3
     5
     7
    11
   ...
   977
   983
   991
   997