Нужна помощь в понимании того, почему множественные левые объединения не возвращаются в снежинке - PullRequest
0 голосов
/ 04 марта 2020

Некоторые проблемы с несколькими левыми соединениями не выполняют то, что я от них ожидаю!

select 
    sent.id,
    sent.ts,
    sent.email,
    delivered.ts,
    type.label,
    min(opens.ts) as first_open,
    count(opens.id) as open_count,
    min(clicks.ts) as first_click,
    count(clicks.id) as click_count
from sent
inner join type on type.id = sent.type_id
left outer join delivered on (delivered.id = sent.id)
left outer join opens on (opens.id = sent.id)
left outer join clicks on (clicks.id = sent.id)
where sent.id = 'a1b1c1d1e1'
group by 
    sent.id,
    sent.ts,
    sent.email,
    delivered.ts,
    type.label,
    opens.id,
    clicks.id
;

Сообщение отправляется, а затем доставляется; это от 1 до 1, но доставленное может не существовать.

После этого сообщение можно открыть (несколько раз) и щелкнуть (несколько раз), все они связаны вместе с sent.id.

Если у меня есть только открытое соединение, оно работает нормально, однако, если у меня есть только соединение щелчков.

Когда я добавляю соединение щелчков, first_click и click_count показывают те же значения, что и открытое.

Я получаю:

1,2020-01-01 00:00:00,a@b.com,2020-01-01 00:00:00,test,2020-01-01 01:00:00,4,2020-01-01 01:00:00,4

Когда это должно быть:

1,2020-01-01 00:00:00,a@b.com,2020-01-01 00:00:00,test,2020-01-01 01:00:00,4,2020-01-01 02:00:00,1

Я пытался запустить без кеш запросов (ALTER SESSION SET USE_CACHED_RESULT = false;) и сделал базовое c зеркало в MySQL, чтобы доказать соединение, и все в порядке.

1 Ответ

1 голос
/ 04 марта 2020

поэтому пытаясь устранить разрыв между описанием проблемы и упомянутыми вами результатами

начать с известных данных

create or replace table sent (id text, ts timestamp_ntz, email text, type_id number);
create or replace table type (id number, label text);
create or replace table delivered(id text, ts timestamp_ntz);
create or replace table opens(id text, ts timestamp_ntz);
create or replace table clicks(id text, ts timestamp_ntz);

insert into sent values ('a1b1c1d1e1', '2020-01-01 01:00', 'a@b.com', 1);
insert into delivered values ('a1b1c1d1e1', '2020-01-01 02:00');
insert into type values (1, 'test');
insert into opens values ('a1b1c1d1e1', '2020-01-01 03:00'),('a1b1c1d1e1', '2020-01-01 04:00'),('a1b1c1d1e1', '2020-01-01 05:00'),('a1b1c1d1e1', '2020-01-01 06:00');
insert into clicks values ('a1b1c1d1e1', '2020-01-01 07:00');

select 
    sent.id
    ,sent.ts
    ,sent.email
    ,delivered.ts
    ,type.label
    ,min(opens.ts) as first_open
    ,count(opens.id) as open_count
    ,min(clicks.ts) as first_click
    ,count(clicks.id) as click_count
from sent
join type on type.id = sent.type_id
left join delivered on (delivered.id = sent.id)
left join opens on (opens.id = sent.id)
left join clicks on (clicks.id = sent.id)
where sent.id = 'a1b1c1d1e1'
group by 1,2,3,4, 5;

Я поменял имена столбцов на их позиции, потому что мне это нравится таким образом, но вам не нужно opens.id или clicks.id, поскольку они не выбраны в неагрегированных столбцах.

 ID TS  EMAIL   TS  LABEL   FIRST_OPEN  OPEN_COUNT  FIRST_CLICK CLICK_COUNT
 a1b1c1d1e1 2020-01-01 01:00:00.000 a@b.com 2020-01-01 02:00:00.000 test    2020-01-01 03:00:00.000 4   2020-01-01 07:00:00.000 4

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

select 
    sent.id
    ,sent.ts
    ,sent.email
    ,delivered.ts
    ,type.label
    ,opens.ts as open_ts
    ,clicks.ts as click_ts
    --,min(opens.ts) as first_open
    --,count(opens.id) as open_count
    --,min(clicks.ts) as first_click
    --,count(clicks.id) as click_count
from sent
join type on type.id = sent.type_id
left join delivered on (delivered.id = sent.id)
left join opens on (opens.id = sent.id)
left join clicks on (clicks.id = sent.id)
where sent.id = 'a1b1c1d1e1'
--group by 1,2,3,4, 5;

дает мне:

 ID TS  EMAIL   TS  LABEL   OPEN_TS CLICK_TS
 a1b1c1d1e1 2020-01-01 01:00:00.000 a@b.com 2020-01-01 02:00:00.000 test    2020-01-01 03:00:00.000 2020-01-01 07:00:00.000
 a1b1c1d1e1 2020-01-01 01:00:00.000 a@b.com 2020-01-01 02:00:00.000 test    2020-01-01 04:00:00.000 2020-01-01 07:00:00.000
 a1b1c1d1e1 2020-01-01 01:00:00.000 a@b.com 2020-01-01 02:00:00.000 test    2020-01-01 05:00:00.000 2020-01-01 07:00:00.000
 a1b1c1d1e1 2020-01-01 01:00:00.000 a@b.com 2020-01-01 02:00:00.000 test    2020-01-01 06:00:00.000 2020-01-01 07:00:00.000

, что то, что я ожидал от эфирных LEFT или обычных INNER соединений ... не стесняйтесь обновлять с SQL, чтобы дать вам неработающие результаты, и перечисленной версией вывода, как указано выше, чтобы получить лучшее объяснение.

...