Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Formato de data e esclarecimento de consulta SQL


Isso é um monte de perguntas para um tópico .. mas vou tentar resolver a maioria deles. (A primeira pergunta que você pode responder a si mesmo, apenas tentando;-)

No que diz respeito à consulta, mesmo que tenha sido executada sem erros - ela pode ser melhorada. Não vou reescrever a consulta para você, mas aqui estão os principais problemas

  • Primeiro, nunca use valores brutos do cliente diretamente no SQL. Sempre use cfqueryparam para proteger contra injeção de sql. Ele também tem outros benefícios, mas esse é crítico em um aplicativo da web.

  • Segundo, você está passando strings de data . As strings de data são ambíguas e podem ser mal interpretadas, dependendo do formato e da ferramenta que faz a análise. É muito melhor usar data objetos em vez de. Uma maneira de fazer isso é usando cfqueryparam e um dos tipos de data:cf_sql_date (somente data) ou cf_sql_timestamp (data e hora).

  • Terceiro, como mencionei em seu outro tópico , você realmente precisa simplificar sua consulta! Essa quantidade de subconsultas já é difícil de manejar. Adicionar filtros de data a cada subconsulta a torna totalmente incontrolável. Eu recomendaria procurar maneiras de simplificá-lo. Sugestão de Ed ofereceu uma possibilidade, reduzindo-o a um único JOIN e algumas chamadas de função.

Bem, na verdade, é assim que seu IDE exibe isso aos humanos. Não é realmente armazenado dessa maneira. Internamente, as datas são armazenadas como números grandes. No entanto, sua consulta precisa levar em conta o fato de que sua coluna armazena uma data e Tempo.

Digamos que você queira recuperar todos os registros datados em junho:
    form.startDate = "06/01/2013"
    form.endDate = "06/30/2013"

Conceitualmente, você precisaria de uma expressão sql como esta:
    WHERE column BETWEEN '06/01/2013 at midnight' AND '06/30/2013 11:59:59 PM' 

No entanto, construir esses valores de data/hora é um pouco desajeitado IMO. Uma maneira mais simples de lidar com isso é usando este paradigma:
   WHERE column >= {startDateAtMidnight}        
   AND   column <  {dayAfterEndDateAtMidnight}

Seu filtro de consulta real seria algo assim:
    WHERE column >= <cfqueryparam value="#form.startDate#" 
                                  cfsqltype="cf_sql_date">
    AND   column <  <cfqueryparam value="#dateAdd('d', 1, form.endDate)#" 
                                  cfsqltype="cf_sql_date">

Adicionando um dia a form.endDate , e usando um < comparação, a consulta resultante é:
    WHERE column >= '2013-06-01 00:00:00'  
    AND   column < '2013-07-01 00:00:00'  

Isso produzirá exatamente os mesmos resultados que a expressão BETWEEN anterior.