Sai*_*ins 5 snowflake-cloud-data-platform snowsql
给定两个日期,我想创建一个数组,其中包含这些日期之间的所有日期,然后对其进行过滤以仅包含一个月末的日期。
例如,使用start_date 2019-01-31和end_date 2019-06-30,我将构造数组
[
  '2019-01-31',
  '2019-02-28',
  '2019-03-31',
  '2019-04-30',
  '2019-05-31',
  '2019-06-30'
]
确切地理解您想要什么有点困难,但是从请求的输出中,看起来数组包含两个日期限制之间的每月日期。我尝试使用JavaScript来实现,以避免出现可怕的“不支持的子查询”错误,但是很难计算日期,设置日期格式并从JavaScript返回到SQL。
所以我最终得到了一个SQL UDF:
CREATE OR REPLACE FUNCTION ARRAY_MONTHS_BETWEEN("FROM" DATE, "TO" DATE)
RETURNS ARRAY AS 
'
  SELECT ARRAY_AGG(DATEADD(MONTH, "MONTH" , "FROM")) A
  FROM (SELECT ROW_NUMBER() OVER (ORDER BY NULL) - 1 "MONTH"
        FROM TABLE(GENERATOR(ROWCOUNT => 1000)))
  WHERE "MONTH" <= CEIL(DATEDIFF(MONTHS, "FROM", "TO"))
';
除了日期常数以外,使用此函数可能会很棘手,因为您可能会打开潘多拉盒型雪花相关子查询框。但是话又说回来,也许不是。
小智 5
Snowflake LAST_DAY函数可用于获取两个日期之间的每个月的最后一天 https://docs.snowflake.net/manuals/sql-reference/functions/last_day.html。
SELECT 
  ARRAY_AGG(LAST_DAY(MY_DATE))
FROM (
  SELECT
    LAST_DAY(DATEADD(MONTH, SEQ4(), '2019-01-31')) AS MY_DATE
  FROM TABLE(GENERATOR(ROWCOUNT=>20000))
  WHERE MY_DATE <= '2019-06-30'
);
上述查询还将结果包装在一个数组中https://docs.snowflake.net/manuals/sql-reference/functions/array_agg.html
[
  "2019-01-31",
  "2019-02-28",
  "2019-03-31",
  "2019-04-30",
  "2019-05-31",
  "2019-06-30"
]
正如已经建议的那样,您可以选择使用此 sql 来创建一个新的用户定义函数:
CREATE FUNCTION LAST_DATES_TO_ARRAY(FROM_D DATE, TO_D DATE)
RETURNS ARRAY 
AS 
$$
SELECT ARRAY_AGG(LAST_DAY(MY_DATE))
FROM (
  SELECT
    LAST_DAY(DATEADD(MONTH, SEQ4(), FROM_D)) AS MY_DATE
  FROM TABLE(GENERATOR(ROWCOUNT=>20000))
  WHERE MY_DATE <= TO_D
)
$$;