Снежинка - обновление с коррелированным подзапросом с использованием timediff - PullRequest
0 голосов
/ 25 февраля 2019

Я выполняю этот запрос к базе данных 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);

База данных возвращает Unsupported subquery type cannot be evaluated.Однако, если я запускаю его без двух последних условий (с TIMEDIFF), он работает без проблем.Я подтвердил, что фактические операторы 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;

, и они работают без проблем.Я не вижу причины, по которой условие TIMEDIFF не позволяет базе данных вернуть результат.Любая идея, что я должен изменить, чтобы это работало?

1 Ответ

0 голосов
/ 20 марта 2019

поэтому, используя следующую настройку

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');

, вы можете видеть, что мы получаем ожидаемые строки

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

, теперь есть два способа получить ваш счет, первый, как у вас,это хорошо, если вы считаете только одну вещь, так как все правила - фильтрация объединения:

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;

или вы можете (в синтаксисе снежинки) переместить счет в сторону агрегирования / выбора и, таким образом, получитьболее одного ответа, если это то, что вам нужно (это то место, где я себя больше нахожу, поэтому я и представляю его):

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;

, включив его в шаблон ОБНОВЛЕНИЯ (см. последний пример в документе)https://docs.snowflake.net/manuals/sql-reference/sql/update.html

вы можете перейти к единственному подвыбору вместо испорченного подзапроса, который не поддерживает снежинка, - это сообщение об ошибке, которое вы получаете.

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; 

Причина добавленияTIMEDIFF превращает ваш запрос в коррелированный подзапрос, каждая строка ОБНОВЛЕНИЯ, теперь относится к результатам подзапроса, корреляции.Обходной путь - сделать «большой, но более простой» подзапрос и присоединиться к нему.

...