简体   繁体   English

雪花中的 generate_series() 等效项

[英]generate_series() equivalent in snowflake

我正在尝试找到与 generate_series() (PostgreSQL 语法)等效的雪花。

SELECT generate_series(timestamp '2017-11-01', CURRENT_DATE, '1 day')

Just wanted to expand on Marcin Zukowski 's comment to say that these gaps started to show up almost immediately after using a date range generated this way in a JOIN .只是想扩展Marcin Zukowski的评论,说这些差距在使用JOIN中以这种方式生成的日期范围后几乎立即开始出现。

We ultimately ended up doing this instead!我们最终还是这样做了!

select
  dateadd(
    day,
    '-' || row_number() over (order by null),
    dateadd(day, '+1', current_date())
  ) as date
from table (generator(rowcount => 90))

I had a similar problem and found an approach, which avoids the issue of a generator requiring a constant value by using a session variable in addition to the already great answers here.我遇到了类似的问题并找到了一种方法,除了这里已经很好的答案之外,它还通过使用会话变量来避免生成器需要常量值的问题。 This is closest to the requirement of the OP to my mind.这在我看来最接近 OP 的要求。

-- set parameter to be used as generator "constant" including the start day
set num_days =  (Select datediff(day, TO_DATE('2017-11-01','YYYY-MM-DD'), current_date()+1));
-- use parameter in bcrowell's answer now
select
  dateadd(
    day,
    '-' || row_number() over (order by null),
    dateadd(day, '+1', current_date())
  ) as date
from table (generator(rowcount => ($num_days)));
-- clean up previously set variable
unset num_days;

Adding this answer for completitude, in case you have an initial and last date:如果您有初始日期和最后日期,请添加此答案以获得完整性:

select -1 + row_number() over(order by 0) i, start_date + i generated_date 
from (select '2020-01-01'::date start_date, '2020-01-15'::date end_date)
join table(generator(rowcount => 10000 )) x
qualify i < 1 + end_date - start_date

I found the generator function in Snowflake quite limiting for all but the simplest use cases.除了最简单的用例之外,我发现 Snowflake 中的生成器功能非常有限。 For example, it was not clear how to take a single row specification, explode it into a table of dates and join it back to the original spec table.例如,不清楚如何获取单行规范,将其分解为日期表并将其连接回原始规范表。

Here is an alternative that uses recursive CTEs.这是使用递归 CTE 的替代方法。

-- A 2 row table that contains "specs" for a date range
create local temp table date_spec as
    select 1 as id, '2022-04-01'::date as start_date, current_date() as end_date
    union all
    select 2, '2022-03-01', '2032-03-30'
;

with explode_date(id, date, next_date, end_date) as (
    select
        id
      , start_date as date          -- start_date is the first date
      , date + 1 as next_date       -- next_date is the date of for the subsequent row in the recursive cte
      , end_date
    from date_spec

    union all

    select
        ds.id
      , ed.next_date                -- the current_date is the value of next_date from above
      , ed.next_date + 1
      , ds.end_date
    from date_spec ds
    join explode_date ed
      on ed.id = ds.id
    where ed.date <= ed.end_date    -- keep running until you hit the end_date
)

select * from explode_date
order by id, date desc
;
WITH RECURSIVE rec_cte AS (
    -- start date
    SELECT '2017-11-01'::DATE as dt
    UNION ALL
    SELECT DATEADD('day',1,dt) as dt
    FROM rec_cte
    -- end date (inclusive)
    WHERE dt < current_date()
)
SELECT * FROM rec_cte

This is how I was able to generate a series of dates in Snowflake.这就是我能够在 Snowflake 中生成一系列日期的方式。 I set row count to 1095 to get 3 years worth of dates, you can of course change that to whatever suits your use case我将行数设置为 1095 以获得 3 年的日期,您当然可以将其更改为适合您的用例的任何内容

select 
    dateadd(day, '-' || seq4(), current_date()) as dte 
from 
    table 
       (generator(rowcount => 1095))

Originally found here 最初在这里找到

EDIT: This solution is not correct.编辑:此解决方案不正确。 seq4 does not guarantee a sequence without gaps. seq4不保证没有间隙的序列。 Please follow other answers, not this one.请关注其他答案,而不是这个答案。 Thanks @Marcin Zukowski for pointing that out.感谢@Marcin Zukowski 指出这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM