在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'
,并尝试将所有日期转换为字符串。似乎没有任何作用。我认为这可能是一个错误。
答案 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 ...