Por que o comportamento de min() é diferente de max()?
Select
max(My_Date) over (order by My_Date) as Max_Datum
, min(My_Date) over (order by My_Date) as Min_Datum
From
(
Select dateadd(m,-1,getdate()) as My_Date
Union all
Select getdate() as My_Date
Union all
Select dateadd(m,1,getdate()) as My_Date
Union all
Select dateadd(m,2,getdate()) as My_Date
) t1
Resultado:
Max_Datum Min_Datum
2024-08-02 16:20:39.733 2024-08-02 16:20:39.733
2024-09-02 16:20:39.733 2024-08-02 16:20:39.733
2024-10-02 16:20:39.733 2024-08-02 16:20:39.733
2024-11-02 16:20:39.733 2024-08-02 16:20:39.733
O problema não são as funções, é sua
OVER
cláusula. Você adicionou umaOVER
cláusula com a cláusulaORDER BY My_Date
, que, de acordo com a documentação , assume como padrão a janela paraRANGE UNBOUNDED PRECEDING AND CURRENT ROW
. Como resultado, oMAX
valor sempre será o valor das linhas atuais, porque essa é a ordem em que os dados estão.Tomemos, por exemplo, os seguintes dados simplificados:
Agora vamos supor que você tenha uma consulta semelhante:
Isso resultaria nos seguintes resultados:
Efetivamente em cada linha você está perguntando o seguinte:
Então, você pode ver que eles
MAX
serão diferentes, masMIN
não serão.O que você provavelmente quer aqui é alterar o
ORDER
, especificar a janela para ser o conjunto de dados inteiro ou não especificar uma janela:O último provavelmente faz mais "sentido" aqui, já que colocar os dados para
MIN
/MAX
na ordem do valor para o qual você está obtendoMIN
/MAX
não faz nada. Se você estivesse ordenando por uma coluna diferente, faria mais sentido.db<>violino
A função MIN olha para trás (incluindo a linha atual e todas as linhas anteriores), então ela continua retornando a data mais antiga que viu.
A função MAX também olha para trás, mas continua atualizando para o último valor máximo encontrado.
MAX(): Conforme você desce as linhas, ele olha para a linha atual e todas as linhas anteriores a ela. Ele sempre escolhe a maior (mais recente) data que viu até agora.
MIN(): Conforme você desce as linhas, ele também olha para a linha atual e todas as linhas anteriores a ela. Mas ele sempre escolhe a menor data (mais antiga) que viu até agora.
Seus dados Você tem estas datas:
2024-08-02 2024-09-02 2024-10-02 2024-11-02 Para MAX():
Começa com 2024-08-02. Passa para 2024-09-02: "Qual é maior? 2024-09-02 ou 2024-08-02?" Mantém 2024-09-02.
O próximo é 2024-10-02: "Qual é maior? 2024-10-02 ou 2024-09-02?" Ele continua 2024-10-02.
Finalmente, 2024-11-02: "Qual é maior? 2024-11-02 ou 2024-10-02?" Ele mantém 2024-11-02. Para MIN():
Começa com 2024-08-02. Passa para 2024-09-02: "Qual é menor? 2024-09-02 ou 2024-08-02?" Mantém 2024-08-02.
O próximo é 2024-10-02: "Qual é menor? 2024-10-02 ou 2024-08-02?" Ele ainda mantém 2024-08-02.
Por fim, 2024-11-02: "Qual é menor? 2024-11-02 ou 2024-08-02?" Ele ainda mantém 2024-08-02.
Para resumir, tanto min() quanto max() olham para todas as linhas anteriores na janela ordenada, mas min() mantém a data mais antiga, e max() atualiza para a mais recente. É por isso que você vê o comportamento que descreveu.