Supondo que eu tenha uma tabela chamada MyTable, com um campo TimeStamp "Created". Eu quero apenas extrair a parte Date desta coluna, e na minha pesquisa encontrei essas alternativas:
SELECT created AS "Original",
date(created) AS "DateFunction",
created::date AS "DoubleColonCast",
cast(created as date) AS "CastFunction",
date_trunc('day', created) AS "DateTrunc"
FROM MyTable
- Em questão de SARGability , qual é o método preferido?
- Qual é a maneira "SQL ANSI" (ou seja, mais portátil)?
- Qual é o mais comum/usado no Postgres?
Como outros apontaram
date(created)
,created::date
ecast(created as date)
são funcionalmente equivalentes.Se você quer ser portátil, use
cast()
. Acho que o::
operador é mais comum em "Terra Postgres". No entanto, nãodate_trunc('day', created)
é equivalente às outras expressões, pois retorna um valor, não um .timestamp
date
Nenhuma dessas expressões fará uso de um índice em
created
- você precisaria criar um índice baseado em expressão com a expressão usada em suas consultas. Acast()
expressão será regravada::
pelo otimizador de consulta, masdate(...)
não. Portanto, se você criar um índice baseado em expressão, usarcast()
ou::
não fará diferença entre a expressão indexada e a usada na consulta.Mas se você usar
date(..)
oudate_trunc()
terá que usar a mesma expressão em suas consultas para fazer uso do indx.created::date
ecast(created as date)
são sintaticamente equivalentes , mascast(created as date)
serão os mais portáteis de todos, pois é o mais próximo do ANSI SQL.Eu não acredito que nenhum deles seja SARGable , mas
date_trunc('day', created)
pode resultar em uma operação de conversão extra para converter o valor de data em um timestamp antes de aplicar sua lógica, então sua melhor aposta, de todos eles, seria usarcast(created as date)
.Todas essas formas são igualmente boas.
Se alguma dessas expressões aparecer em uma
WHERE
cláusula comoentão você tem que criar o índice com exatamente a mesma expressão: