Existe alguma diferença entre as seguintes afirmações?
SELECT DATEADD(MONTH, @SomeInteger * 12, @SomeDate)
SELECT DATEADD(YEAR, @SomeInteger, @SomeDate)
Em outras palavras, existem casos em que eles produziriam resultados diferentes para o mesmo valor de @SomeInteger
e @SomeDate
?
Fiz um teste rápido através do seguinte:
SELECT
*
FROM dbo.DimDate dd
WHERE DATEADD(MONTH, 12, dd.Date) <> DATEADD(YEAR, 1, dd.Date)
que retornou zero registros, mas isso está longe de provar que as duas instruções são equivalentes.
O computer scalar
componente do plano de execução tem exatamente o mesmo custo em ambas as consultas, mas as ScalarOperator
definições são diferentes - parece que o Otimizador de consultas não está convertendo uma instrução em outra.
Obrigado!
Nesse caso, são comportamentos equivalentes, embora as
ScalarOperator
definições sejam diferentes. Isso ocorre porque em outros casos eles não podem ser trocados. Pense sobre:datediff
em dias, que depende de qual mês e também deve levar em conta o ano bissexto.datediff
em segundos que será não determinístico quando houver um segundo bissexto.O SQL Server não ganha nenhuma vantagem alterando a definição de um operador escalar para se parecer mais com a de outro. Qual seria o benefício? Se você disser
WHERE column = 4 * 5
, não seria confuso se o operador escalar dissesseWHERE column = 2 * 10
? Mesmo se você tiver outra consulta em algum lugar que use2 * 10
?Em outras palavras, se você disser
DATEADD(MONTH, n*12, ...
que não vejo motivo algum para o SQL Server alterar essa expressãoDATEADD(YEAR, n, ...
apenas porque todos sabemos que há 12 meses em um ano. Você pediu um delta por meses, não anos, então é isso que a expressão deve mostrar.