Ao subtrair dois valores de data ou timestamp no MaxCompute, o resultado é um INTERVAL — uma representação tipada do intervalo de tempo entre eles. O MaxCompute oferece dois subtipos de INTERVAL: INTERVAL_YEAR_MONTH para intervalos baseados em calendário (anos e meses) e INTERVAL_DAY_TIME para intervalos de duração fixa (dias, horas, minutos e segundos). Como esses subtipos utilizam escalas de tempo diferentes, não é possível combiná-los em operações aritméticas.
Pré-requisitos
Antes de começar, verifique se você:
-
Ativou o sistema de tipos do MaxCompute 2.0 ao executar a seguinte instrução na sessão:
SET odps.sql.type.system.odps2=true;
INTERVAL_YEAR_MONTH
O tipo INTERVAL_YEAR_MONTH armazena um intervalo em anos e meses.
Sintaxe
Use o padrão de string exibido na coluna String pattern. Para expressar um intervalo negativo, adicione o prefixo - ao valor do padrão.
|
Sintaxe |
Padrão de string |
Descrição |
Exemplo |
|
|
|
Componentes de ano e mês |
|
|
|
|
Apenas o componente de ano |
|
|
|
|
Apenas o componente de mês |
|
Intervalos válidos e comportamento de estouro
|
Campo |
Intervalo válido |
Quando usado isoladamente |
Quando combinado com outro campo |
|
year |
0–9.999 |
Deve permanecer dentro do intervalo |
Deve permanecer dentro do intervalo |
|
month |
0–11 |
Pode exceder 11 — o estouro converte para anos |
Não pode exceder 11 — exceder causa erro de parse |
Exemplo de estouro apenas com mês
Se você especificar apenas o intervalo MONTH, o valor poderá ser maior que 11. O MaxCompute converte automaticamente os meses excedentes em anos:
SELECT INTERVAL '200' MONTH;
Resultado:
+------+
| _c0 |
+------+
| 16-8 |
+------+
200 meses equivalem a 16 anos e 8 meses.
YEAR TO MONTH — mês fora do intervalo (erro)
Ao usar YEAR TO MONTH, o valor do mês deve estar entre 0 e 11:
SELECT INTERVAL '-2021-12' YEAR TO MONTH;
Resultado:
FAILED: ODPS-0130161:[1,17] Parse exception - cannot parse -2021-12 as a valid INTERVAL_DAY_TIME
INTERVAL_DAY_TIME
O tipo INTERVAL_DAY_TIME armazena um intervalo em dias, horas, minutos, segundos e frações de segundo.
Sintaxe
Use o padrão de string exibido na coluna String pattern. Para expressar um intervalo negativo, adicione o prefixo - ao valor do padrão.
|
Sintaxe |
Padrão de string |
Descrição |
Exemplo |
|
|
|
Apenas o componente de dia |
|
|
|
|
Apenas o componente de hora |
|
|
|
|
Apenas o componente de minuto |
|
|
|
|
Apenas o componente de segundo (suporta frações de segundo) |
|
|
|
|
Componentes de dia e hora |
|
|
|
|
Componentes de dia, hora e minuto |
|
|
|
|
Componentes de dia, hora, minuto e segundo |
|
|
|
|
Componentes de hora e minuto |
|
|
|
|
Componentes de hora, minuto e segundo |
|
|
|
|
Componentes de minuto e segundo |
|
Intervalos válidos e comportamento de estouro
|
Campo |
Intervalo válido |
Quando usado isoladamente |
Quando combinado com outro campo |
|
day |
0–2.147.483.647 |
Deve permanecer dentro do intervalo |
Deve permanecer dentro do intervalo |
|
hour |
0–23 |
Pode exceder 23 — o estouro converte para dias |
Não pode exceder 23 |
|
minute |
0–59 |
Pode exceder 59 — o estouro converte para horas |
Não pode exceder 59 |
|
second |
0–59,999999999 |
Pode exceder 59 — o estouro converte para minutos |
Não pode exceder 59,999999999 |
Exemplo de estouro com unidade única
Caso você especifique apenas uma unidade de tempo, o valor poderá ultrapassar o limite superior. O MaxCompute converte automaticamente o excesso para a próxima unidade maior:
SELECT INTERVAL '24' HOUR; -- Equivalent to INTERVAL '1' DAY
SELECT INTERVAL '60' MINUTE; -- Equivalent to INTERVAL '1' HOUR
SELECT INTERVAL '6000' SECOND; -- Equivalent to INTERVAL '1:40' HOUR TO MINUTE
Valor fora do intervalo em formato de múltiplas unidades (erro)
Ao usar um formato com múltiplas unidades, cada campo deve respeitar o intervalo válido:
SELECT INTERVAL '23:60' HOUR TO MINUTE;
Resultado:
FAILED: ODPS-0130161:[1,17] Parse exception - cannot parse 23:60 as a valid INTERVAL_DAY_TIME
Operações compatíveis
Somar ou subtrair valores INTERVAL do mesmo tipo
As operações de adição e subtração funcionam entre valores INTERVAL do mesmo tipo. Não há suporte para operações entre INTERVAL_YEAR_MONTH e INTERVAL_DAY_TIME, pois esses dois tipos usam escalas de tempo distintas (meses de calendário versus segundos de duração fixa).
Somar dois valores INTERVAL_DAY_TIME:
SELECT INTERVAL '24' HOUR + INTERVAL '23' HOUR;
Resultado:
+----------------------+
| _c0 |
+----------------------+
| 1 23:00:00.000000000 |
+----------------------+
Subtrair dois valores INTERVAL_DAY_TIME:
SELECT INTERVAL '24' HOUR + INTERVAL '-23' HOUR;
Resultado:
+----------------------+
| _c0 |
+----------------------+
| 0 01:00:00.000000000 |
+----------------------+
Subtrair dois valores INTERVAL_YEAR_MONTH:
SELECT INTERVAL '5-1' YEAR TO MONTH - INTERVAL '9-2' YEAR TO MONTH;
Resultado:
+------+
| _c0 |
+------+
| -4-1 |
+------+
Aritmética entre tipos diferentes (erro):
SELECT INTERVAL '2000-1' YEAR TO MONTH + INTERVAL '1 23:59:59.999' DAY TO SECOND;
Resultado:
FAILED: ODPS-0130071:[1,8] Semantic analysis exception - invalid operand type(s) INTERVAL_YEAR_MONTH,INTERVAL_DAY_TIME for operator '+'
Subtrair valores DATE, TIMESTAMP ou TIMESTAMP_NTZ para obter um INTERVAL_DAY_TIME
A subtração de dois valores DATE, TIMESTAMP ou TIMESTAMP_NTZ retorna um resultado INTERVAL_DAY_TIME. Não há suporte para subtração de dois valores DATETIME.
Subtrair dois valores DATE:
SELECT DATE '2021-10-29' - DATE '2024-11-29';
Resultado:
+--------------------------+
| _c0 |
+--------------------------+
| -1127 00:00:00.000000000 |
+--------------------------+
Subtrair dois valores TIMESTAMP:
SELECT TIMESTAMP '2024-11-29 00:01:10' - TIMESTAMP'2021-10-29 00:01:00';
Resultado:
+-------------------------+
| _c0 |
+-------------------------+
| 1127 00:00:10.000000000 |
+-------------------------+
Subtração de DATETIME (erro):
SELECT DATETIME '2024-11-11 00:00:00' - DATETIME'2021-11-11 00:00:00';
Resultado:
FAILED: ODPS-0130071:[1,8] Semantic analysis exception - invalid operand type(s) DATETIME,DATETIME for operator '-'
Somar ou subtrair um INTERVAL de um valor DATE, TIMESTAMP ou TIMESTAMP_NTZ
Somar ou subtrair um INTERVAL de um valor DATE, TIMESTAMP ou TIMESTAMP_NTZ retorna um valor do mesmo tipo. Essa operação não é compatível com valores DATETIME.
Subtrair um INTERVAL_YEAR_MONTH de um DATE:
SELECT DATE '2021-11-11' - INTERVAL '-1' MONTH;
Resultado:
+------------+
| _c0 |
+------------+
| 2021-12-11 |
+------------+
Subtrair um INTERVAL_DAY_TIME de um TIMESTAMP_NTZ:
SELECT TIMESTAMP_NTZ'2024-11-29 00:01:10' - INTERVAL '1 23' DAY TO HOUR;
Resultado:
+---------------------+
| _c0 |
+---------------------+
| 2024-11-27 01:01:10 |
+---------------------+
DATETIME com INTERVAL (erro):
SELECT DATETIME '2024-11-11 00:00:00' - INTERVAL '1 23' DAY TO HOUR;
Resultado:
FAILED: ODPS-0130071:[1,8] Semantic analysis exception - invalid operand type(s) DATETIME,INTERVAL_DAY_TIME for operator '-'