2016-11-17 2 views
2

Я вижу неожиданное поведение в аналитической функции VIRUE() с помощью параметра IGNORE NULLS. Кажется, он возвращает NULL, когда это не должно.Неожиданное поведение в FIRST_VALUE() с IGNORE NULLS (Vertica)

Проблема возникает в этом крошечном таблице:

drop table if exists temp; 
create table temp (time_ timestamp(6), name varchar(10)); 
insert into temp (time_) values ('2016-03-18 20:32:16.144'); 
insert into temp (time_, name) values ('2016-03-18 20:52:09.062', 'abc'); 

Вот содержание таблицы (выберите * от температуры):

time_     | name 
------------------------+-------- 
2016-03-18 20:32:16.144 | <null> 
2016-03-18 20:52:09.062 | abc 

Вот запрос я бегу:

select time_, 
    first_value(name ignore nulls) over (order by time_) first_name 
from temp; 

Вот результаты этого запроса возвращает:

time_     | first_name 
------------------------+------------ 
2016-03-18 20:32:16.144 | <null> 
2016-03-18 20:52:09.062 | abc 

Вот результаты, которые я бы ожидать (и желания) из этого запроса:

time_     | first_name 
------------------------+------------ 
2016-03-18 20:32:16.144 | abc 
2016-03-18 20:52:09.062 | abc 

есть ли выше запрос очень фундаментальная синтаксическая ошибка? Эта проблема возникает в Vertica Community Edition 7.1.1.

ответ

1

Функция работает, как ожидалось.
over (order by time_) - это ярлык для over (order by time_ range unbounded preceding), который является ярлыком для over (order by time_ range between unbounded preceding and current row), что означает, что каждая строка видит только предшествующие строки, включая себя.
Первая строка видит только себя, поэтому в ее области не существует значения NULL.

Если вы хотите, чтобы первый не пустое значение всего объема, вы должны указать полный объем:

first_value(name ignore nulls) over 
    (order by time_ range between unbounded preceding and unbounded following) first_name 

Нет, это определенно не ошибка.

Возможно, вы использовали синтаксис, например sum(x) over (order by y), для запуска итогов, а окно по умолчанию RANGE UNBOUNDED PRECEDING показалось вам очень естественным.
Поскольку вы не определили явное окно для функции FIRST_VALUE, вы используете одно и то же окно по умолчанию.

Вот еще один тест:

ts val 
-- ---- 
1 NULL 
2 X 
3 NULL 
4 Y 
5 NULL 

Что вы ожидаете получить от следующей функции?

last_value (val) order (by ts) 

Что вы ожидаете получить от следующей функции?

last_value (val ignore nulls) order (by ts) 
+0

Очень интересно. Кажется, это скорее ошибка, чем какая-то особенность, но я рад узнать всю историю. Спасибо! – verbatross

+0

@verbatross, см. Мой отредактированный ответ. –

+0

Спасибо за дополнительные примеры! Супер полезно. – verbatross

2

Это где мое мышление берет меня

select time_ 
     ,first_value(name) over (order by case when name is null then 1 else 0 end,time_) FirstName 
from temp A 
order by time_ 

Возвращает

time_    FirstName 
20:32:16.1440000 abc 
20:52:09.0620000 abc 
+0

Спасибо за обходной путь. (В Vertica CE 7.1.1 этот точный синтаксис не работает, но вы можете сделать: 'select time_, first_value (name) over (по порядку, когда имя равно null, а затем 1 else 0 end, time_) first_name из temp'). Но разве IGNORE NULLS не должны делать это точно? – verbatross

+0

@verbatross Счастлив, что вы смогли настроить. Потрясенный, что он не поддерживает IIF() –

+0

@verbatross search ... но до сих пор я вижу только игнорирование нулей в AWS –