在Snowflake UDF中使用两个不同的日期比较“无法评估不支持的子查询类型”

时间:2019-11-07 23:08:45

标签: snowflake-data-warehouse

在Snowflake中,按原样使用UDF时,出现上述错误(完全合法的查询):

SELECT
  dd.date,
  person_count(dd.date) AS cnt
FROM dim_date dd
WHERE dd.date BETWEEN '2019-11-01' and '2019-11-07'

基本上,这可行:

CREATE OR REPLACE FUNCTION person_count(d date)
  RETURNS number 
  AS 
  $$
  SELECT COUNT(DISTINCT person_id) 
   FROM persons
   WHERE (deceased_date > d)
  $$;

这会产生错误:

CREATE OR REPLACE FUNCTION person_count(d date)
  RETURNS number 
  AS 
  $$
  SELECT COUNT(DISTINCT person_id) 
   FROM persons
   WHERE (deceased_date = '1901-01-01' OR deceased_date > d)
  $$;

我尝试在日期字符串上使用TO_DATE。我尝试使用deceased_date < '1901-01-02',并尝试将所有日期转换为字符串。似乎没有任何作用。我认为这可能是一个错误。

3 个答案:

答案 0 :(得分:0)

同意第一个代码有效,

create or replace table persons (person_id number, deceased_date date);
insert into persons values (1,'2019-10-01'),(1,'2019-09-01'),(2,'1901-01-01'),(3,'2019-11-04');

SELECT COUNT(DISTINCT person_id) 
    FROM persons
    WHERE (deceased_date = '1901-01-01' OR deceased_date > '2019-11-04');

CREATE OR REPLACE FUNCTION person_count(d date)
    RETURNS number 
    AS 
    $$
    SELECT COUNT(DISTINCT person_id) 
     FROM persons
     WHERE (deceased_date > d)
    $$;

 select column1 as date
    ,person_count(column1) as cnt 
 from values ('2019-11-01'), ('2019-11-02'), ('2019-11-03'), ('2019-11-04'), ('2019-11-05'), ('2019-11-06'), ('2019-11-07')
 order by 1;

但是这些替代方法却没有。       创建或替换功能person_count(日期)       退货编号       如       $$       SELECT COUNT(DISTINCT person_id)        来自人        在哪里(decaesed_date ='1901-01-01'或deceased_date> d)       $$;

  CREATE OR REPLACE FUNCTION person_count(d date)
  RETURNS number 
  AS 
  $$
  SELECT COUNT(DISTINCT person_id)
  FROM (
    SELECT person_id FROM PERSONS WHERE deceased_date > d
    UNION 
    SELECT person_id FROM PERSONS WHERE deceased_date = '1901-01-01'
  )
  $$;  

原因是,当他们扩展FUNCTION时,会将其转换为相关的子查询(即使可以通过JOIN完成),这是唯一非常简单的相关子查询的工作,您无法控制这个。当您想使用TABLE FUNCTIONS作为查询表时,我们为此大吃一惊。在一个地方,我们只是推出了一个CASE语句以避免查找(粗略),而在另一个地方,我们使用Javascript UDF进行了查找。

但这从根本上来说是一个错误,所以我会报告它。

答案 1 :(得分:0)

问题在于子查询支持中的OR谓词有一些限制。

答案 2 :(得分:0)

我相信UDF与该错误无关。似乎Snowflake尽可能在查询解析过程中进行语法替换,在这种情况下最终结果为:

SELECT
  dd.date,
  (SELECT COUNT(DISTINCT person_id) 
   FROM persons
   WHERE (deceased_date = '1901-01-01' OR deceased_date > dd.date)) AS cnt
FROM dim_date dd
WHERE dd.date BETWEEN '2019-11-01' and '2019-11-07';

哪个会产生完全相同的错误。正如Seeling Cheung所提到的,只有在存在多个WHERE条件时,此操作才会失败。

将子查询(相关或不相关)与多条件过滤相结合的查询解析对于Snowflake似乎是一个连续的问题。 Bug in Date Cast ...