简体   繁体   English

Snowflake-使用timediff更新相关子查询

[英]Snowflake - update with correlated subquery using timediff

I am running this query on Snowflake Database: 我在Snowflake数据库上运行此查询:

UPDATE "click" c
SET "Registration_score" =
(SELECT COUNT(*) FROM "trackingpoint" t
WHERE 1=1
AND c."CookieID" = t."CookieID"
AND t."page" ilike '%Registration complete'
AND TIMEDIFF(minute,c."Timestamp",t."Timestamp") < 4320
AND TIMEDIFF(second,c."Timestamp",t."Timestamp") > 0);

The Database returns Unsupported subquery type cannot be evaluated . Unsupported subquery type cannot be evaluated数据库返回的Unsupported subquery type cannot be evaluated However, if I run it without the last two conditions (with TIMEDIFF), it works without problem. 但是,如果我在没有最后两个条件的情况下运行它(使用TIMEDIFF),则它可以正常工作。 I confirmed that the actual TIMEDIFF statements are alright with these queries: 我确认实际的TIMEDIFF语句对这些查询是正确的:

select count(*) from "trackingpoint"
where TIMEDIFF(minute, '2018-01-01', "Timestamp") > 604233;
select count(*) from "click"
where TIMEDIFF(minute, '2018-01-01', "Timestamp") > 604233;

and these work without problem. 这些都可以正常工作。 I don't see a reason why the TIMEDIFF condition shoud prevent the database from returning the result. 我看不到为什么TIMEDIFF条件应阻止数据库返回结果的原因。 Any idea what should I alter to make it work? 任何想法我应该改变使其工作吗?

so using the following setup 所以使用以下设置

create table click (id number, 
   timestamp timestamp_ntz,
   cookieid number,
   Registration_score number);
create table trackingpoint(id number, 
   timestamp timestamp_ntz, 
   cookieid number, 
   page text );


insert into click values (1,'2018-03-20', 101, 0),
    (2,'2019-03-20', 102, 0);
insert into trackingpoint values (1,'2018-03-20 00:00:10', 101, 'user reg comp'),
    (2,'2018-03-20 00:00:11', 102, 'user reg comp'),
    (3,'2018-03-20 00:00:13', 102, 'pet reg comp'),
    (4,'2018-03-20 00:00:15', 102, 'happy dance');

you can see we get the rows we expect 您可以看到我们得到了我们期望的行

select c.*, t.*
from click c
join trackingpoint t 
    on c.cookieid = t.cookieid ;

now there are two ways to get your count, the first as you have it, which is good if your counting only one thing, as all the rules are join filtering: 现在有两种获取计数的方法,第一种是拥有计数的,如果只计数一件事,这是个好方法,因为所有规则都是联接过滤:

select c.id,
  count(1) as new_score
from click c
join trackingpoint t 
    on c.cookieid = t.cookieid
    and t.page ilike '%reg comp'
    and TIMEDIFF(minute, c.timestamp, t.timestamp) < 4320
group by 1;

or you can (in snowflake syntax) move the count to the aggregate/select side,and thus get more than one answer if that's what you need (this is the place I find myself more, thus why I present it): 或者,您也可以(使用雪花式语法)将计数移到“合计/选择”一侧,如果这是您所需要的,则可以得到多个答案(这是我发现自己比较多的地方,因此我提出了这个原因):

select c.id,
    sum(iff(t.page ilike '%reg comp' AND TIMEDIFF(minute, c.timestamp, t.timestamp) < 4320, 1, 0)) as new_score
from click c
join trackingpoint t 
    on c.cookieid = t.cookieid
group by 1;

thus plugging this into the UPDATE pattern (see last example in the doc's) https://docs.snowflake.net/manuals/sql-reference/sql/update.html 因此,将其插入UPDATE模式(请参阅文档的最后一个示例) https://docs.snowflake.net/manuals/sql-reference/sql/update.html

you can move to a single subselect instead of a corolated subquery which snowflake doesn't support, which is the error message you are getting. 您可以移至单个子选择,而不是雪花不支持的合并子查询,这是您收到的错误消息。

UPDATE click c
SET Registration_score = s.new_score
from (
    select ic.id,
        count(*) as new_score
    from click ic
    join trackingpoint it 
        on ic.cookieid = it.cookieid
        and it.page ilike '%reg comp'
        and TIMEDIFF(minute, ic.timestamp, it.timestamp) < 4320
    group by 1) as s
WHERE c.id = s.id; 

The reason add the TIMEDIFF turns your query into a correlated sub-query, is each row of the UPDATE, now relates to the sub-query results, the correlation. 添加TIMEDIFF的原因将您的查询变成一个相关的子查询,即UPDATE的每一行,现在与子查询的结果相关。 The work around is to make "big but simpler" sub-query and join to that. 解决方法是使“大而简单”的子查询加入其中。

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

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