Ошибка при применении функций to_date() и add_months в Spark SQL

#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 значение Y week 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