#sql #apache-spark #hive #apache-spark-sql
#sql #apache-spark #улей #apache-spark-sql
Вопрос:
У меня следующая таблица hive. Столбец cycle_month
содержит значения в формате ГГГГ.
--------------- -------------- ------------
| column_value | metric_name |cycle_month |
--------------- -------------- ------------
| A37B | Mean | 202005 |
| ACCOUNT_ID | Mean | 202005 |
| ANB_200 | Mean | 202005 |
| ANB_201 | Mean | 202006 |
| AS82_RE | Mean | 202006 |
| ATTR001 | Mean | 202007 |
| ATTR001_RE | Mean | 202007 |
| ATTR002 | Mean | 202008 |
| ATTR002_RE | Mean | 202008 |
| ATTR003 | Mean | 202009 |
| ATTR004 | Mean | 202009 |
| ATTR005 | Mean | 202009 |
| ATTR006 | Mean | 202010 |
Мне нужно написать динамический запрос, чтобы получить значения между переданным пользователем значением cycle_month и cycle_month — 4 месяца.
Запрос Spark SQL:
select column_name, metric_name from table where cycle_month between add_months(to_date(202010,'YYYYMM'),-4) and 202010
Получение ошибки
[Ошибка 10015]: Строка 1: несоответствие длины 323 аргументов «ГГГГ»: для to_date() требуется 1 аргумент, получено 2 (состояние = 21000, код = 10015)
Ожидаемый результат:
--------------- -------------- ------------
| column_value | metric_name |cycle_month |
--------------- -------------- ------------
| ANB_201 | Mean | 202006 |
| AS82_RE | Mean | 202006 |
| ATTR001 | Mean | 202007 |
| ATTR001_RE | Mean | 202007 |
| ATTR002 | Mean | 202008 |
| ATTR002_RE | Mean | 202008 |
| ATTR003 | Mean | 202009 |
| ATTR004 | Mean | 202009 |
| ATTR005 | Mean | 202009 |
| ATTR006 | Mean | 202010 |
Ответ №1:
Y
неправильный формат для year; он должен быть y
. Вы должны использовать yyyyMM
. См. https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html за подробностями.
SELECT
column_name, metric_name, cycle_month
FROM
table
WHERE
to_date(cycle_month, 'yyyyMM') BETWEEN
add_months(to_date(202010, 'yyyyMM'), -4)
AND
to_date(202010, 'yyyyMM')
Ответ №2:
to_date
функция ожидает строку в качестве входных данных и возвращается date
для изменения даты, чтобы YYYYMM
использовать date_format
функцию, наконец, приведенную date
к int
.
Try with this query
select column_name, metric_name from table where cycle_month between int(date_format(add_months(to_date('202010','YYYYMM'),-4),'YYYYMM')) and 202010
UPDATE:
sql("select int(date_format(add_months(to_date('202010','YYYYMM'),-4),'YYYYMM'))").show()
# ------------------------------------------------------------------------------------------------
#|CAST(date_format(CAST(add_months(to_date('202010', 'YYYYMM'), -4) AS TIMESTAMP), YYYYMM) AS INT)|
# ------------------------------------------------------------------------------------------------
#| 201908|
# ------------------------------------------------------------------------------------------------
Комментарии:
1. Это по-прежнему выдает ту же ошибку, потому что формат даты неверен — он должен быть
yyyyMM
, а неYYYYMM
2.@mck, к вашему сведению, он не выдаст ошибку, если вы укажете
YYYYMM
значение Yweek of the year
. автор вопроса упомянулY
, что мы не можем слепо предполагатьy
, а также, пожалуйста, выполняйте команды перед публикацией комментариев / понижений (проверьте раздел «Мои обновления» в ответе).3. Команда в разделе update выдает ошибку в Spark 3.0.0:
org.apache.spark.SparkUpgradeException: You may get a different result due to the upgrading of Spark 3.0: Fail to recognize 'YYYYMM' pattern in the DateTimeFormatter. 1) You can set spark.sql.legacy.timeParserPolicy to LEGACY to restore the behavior before Spark 3.0. 2) You can form a valid datetime pattern with the guide from https://spark.apache.org/docs/latest/sql-ref-datetime-pattern.html
4. Также я полагаю, что в 99,99% случаев
y
это то, что хочет пользователь, а не неделя года.5. Оба ответа работают для меня 🙂 Я использую Spark 2.4.0