Я ищу SQL-эквивалент SET varname = value
в Hive QL
Я знаю, что могу сделать что-то вроде этого:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
Но тогда я получаю эту ошибку:
символ '@' здесь не поддерживается
Я ищу SQL-эквивалент SET varname = value
в Hive QL
Я знаю, что могу сделать что-то вроде этого:
SET CURRENT_DATE = '2012-09-16';
SELECT * FROM foo WHERE day >= @CURRENT_DATE
Но тогда я получаю эту ошибку:
символ '@' здесь не поддерживается
Для замены переменных вам нужно использовать специальную hiveconf. например.
hive> set CURRENT_DATE='2012-09-16';
hive> select * from foo where day >= '${hiveconf:CURRENT_DATE}'
Аналогично, вы можете передать командную строку:
% hive -hiveconf CURRENT_DATE='2012-09-16' -f test.hql
Обратите внимание, что существуют переменные env и system, поэтому вы можете ссылаться на ${env:USER}
например.
Чтобы просмотреть все доступные переменные, из командной строки запустите
% hive -e 'set;'
или из приглашения hive, запустите
hive> set;
Update:
Я также начал использовать переменные hivevar, помещая их в hql-фрагменты, которые я могу включить из CLI в hive, используя команду source
(или передать как -i из командной строки).
Преимущество здесь в том, что переменная может быть затем использована с префиксом hivevar или без него и позволяет что-то сродни глобальному или локальному использованию.
Итак, предположим, что у меня есть setup.hql, который устанавливает переменную tablename:
set hivevar:tablename=mytable;
тогда я могу привести в улей:
hive> source /path/to/setup.hql;
и использовать в запросе:
hive> select * from ${tablename}
или
hive> select * from ${hivevar:tablename}
Я также мог бы установить "локальное" имя-табло, что повлияет на использование ${tablename}, но не ${hivevar: tablename}
hive> set tablename=newtable;
hive> select * from ${tablename} -- uses 'newtable'
против
hive> select * from ${hivevar:tablename} -- still uses the original 'mytable'
Вероятно, это не означает слишком многого из CLI, но может иметь hql в файле, который использует источник, но установить некоторые из переменных "локально" для использования в остальной части script.
В большинстве ответов здесь предлагается использовать пространство имен hiveconf
или hivevar
для хранения переменной. И все эти ответы верны. Однако есть еще одно пространство имен.
Всего доступно три namespaces
для хранения переменных.
И поэтому, если вы храните переменную как часть запроса (например, date или product_number), вы должны использовать пространство имен hivevar
а не пространство имен hiveconf
.
И вот как это работает.
hiveconf по-прежнему является пространством имен по умолчанию, поэтому, если вы не предоставите никакого пространства имен, он сохранит вашу переменную в пространстве имен hiveconf.
Однако, когда речь идет о ссылке на переменную, это не так. По умолчанию это относится к пространству имен hivevar. Смущает, верно? Это может стать понятнее со следующим примером.
Если вы не предоставите пространство имен, как указано ниже, переменная var
будет храниться в пространстве имен hiveconf
.
set var="default_namespace";
Итак, для доступа к этому вам нужно указать пространство имен hiveconf
select ${hiveconf:var};
И если вы не предоставите пространство имен, оно выдаст вам ошибку, как указано ниже, причина в том, что по умолчанию, если вы пытаетесь получить доступ к переменной, она проверяет hivevar
пространство имен hivevar
. А в hivevar
нет переменной с именем var
select ${var};
Мы явно предоставили пространство имен hivevar
set hivevar:var="hivevar_namespace";
поскольку мы предоставляем пространство имен, это будет работать.
select ${hivevar:var};
И по умолчанию рабочая область, используемая при обращении к переменной - это hivevar
, также будет работать следующее.
select ${var};
Пробовали ли вы использовать знак доллара и скобки следующим образом:
SELECT *
FROM foo
WHERE day >= '${CURRENT_DATE}';
Два простых способа:
Использование улья конф
hive> set USER_NAME='FOO';
hive> select * from foobar where NAME = '${hiveconf:USER_NAME}';
Использование улья
На вашем CLI установите Vars, а затем используйте их в улье
set hivevar:USER_NAME='FOO';
hive> select * from foobar where NAME = '${USER_NAME}';
hive> select * from foobar where NAME = '${hivevar:USER_NAME}';
Документация: https://cwiki.apache.org/confluence/display/Hive/LanguageManual+VariableSubstitution
Следует помнить, что нужно задавать строки, а затем обращаться к ним. Вы должны убедиться, что цитаты не сталкиваются.
set start_date = '2019-01-21';
select ${hiveconf:start_date};
При установке дат обращайтесь к ним в коде, так как строки могут конфликтовать. Это не будет работать с указанным выше значением start_date.
'${hiveconf:start_date}'
Мы должны помнить, что нельзя указывать дважды одинарные или двойные кавычки для строк при обращении к ним в запросе.
Попробуйте этот метод:
set t=20;
select *
from myTable
where age > '${hiveconf:t}';
это хорошо работает на моей платформе.
Вы можете экспортировать переменную в экспорте скрипта оболочки CURRENT_DATE = "2012-09-16"
Тогда в hiveql вам нравится SELECT * FROM foo WHERE day> = '$ {env: CURRENT_DATE}'
На всякий случай, если кому-то нужно параметризовать запрос улья через cli.
Например:
hive_query.sql
SELECT * FROM foo WHERE day >= '${hivevar:CURRENT_DATE}'
Теперь выполните вышеуказанный файл sql из cli:
hive --hivevar CURRENT_DATE="2012-09-16" -f hive_query.sql
Вы можете сохранить вывод другого запроса в переменной, а затем вы можете использовать его в своем коде:
set var=select count(*) from My_table;
${hiveconf:var};