#sql #impala #hue
#sql #impala #оттенок
Вопрос:
У меня есть следующий код:
select *, lead(session_end_type) over (partition by user_id, session_id order by user_id, session_id, log_time) as next_session_end_type
from table_name;
Однако, похоже, что это приводит к разным результатам каждый раз, когда я его запускаю.
В чем разница?
Заранее спасибо!
(Я проверил, что код выдает разные результаты с помощью следующего кода:
create table t1
select *, lead(session_end_type) over (partition by user_id, session_id order by user_id, session_id, log_time) as next_session_end_type
from table_name;
create table t2
select *, lead(session_end_type) over (partition by user_id, session_id order by user_id, session_id, log_time) as next_session_end_type
from table_name;
select count (*) from
(
select * from t1
union
select * from t2
) as t;
Результирующее количество строк отличается от количества строк t1 и количества строк t2; это означает, что результат t1 и t2 отличается.)
Комментарии:
1. Является ли комбинация
user_id, session_id, log_time
уникальной в таблице? В противном случае вы можете получить немного разные заказы и, следовательно, разные значения lead и, следовательно, разные подсчеты.2. @ThorstenKettner Спасибо! Я предполагал, что они уникальны, но оказалось, что это не так! Не думал об ошибке журнала!
3. Кстати, в этом нет необходимости
order by user_id, session_id
, эти столбцы уже находятся вpartition by
4. @dnoeth О, спасибо, что дали мне знать 🙂
Ответ №1:
Во-первых, нет необходимости повторять partition by
столбцы в order by
. Вы можете упростить это до:
lead(session_end_type) over (partition by user_id, session_id order by log_time) as next_session_end_type
Во-вторых, если log_time
не является уникальным для данного user_id
/ session_id
, то результаты нестабильны. Помните, что таблицы SQL представляют собой неупорядоченные наборы, поэтому, если в ключах сортировки есть связи, тогда нет «естественного» порядка, к которому можно вернуться.
Вы можете проверить это с помощью:
select user_id, session_id, log_time, count(*)
from table_name
group by user_id, session_id, log_time
having count(*) > 1
order by count(*) desc;
Если у вас есть столбец, который однозначно идентифицирует каждую строку (или каждую строку сеанса пользователя / пользователя), затем включите ее в order by
:
lead(session_end_type) over (partition by user_id, session_id
order by log_time, <make it stable column>) as next_session_end_type
)