Mysql
 sql >> Database >  >> RDS >> Mysql

Formato della data e chiarimento della query SQL

Ci sono molte domande per un thread .. ma cercherò di affrontarne la maggior parte. (La prima domanda a cui puoi rispondere tu stesso, semplicemente provandola;-)

Per quanto riguarda la query, anche se è stata eseguita senza errori, può essere migliorata. Non riscriverò la query per te, ma qui ci sono i problemi principali

  • Primo, mai utilizzare i valori client non elaborati direttamente in SQL. Usa sempre cfqueryparam per proteggersi dall'iniezione di sql. Ha anche altri vantaggi, ma quello è fondamentale in un'applicazione web.

  • In secondo luogo, stai passando stringhe di data . Le stringhe di data sono ambigue e possono essere interpretate erroneamente, a seconda del formato e dello strumento che esegue l'analisi. È molto meglio usare la data oggetti invece. Un modo per farlo è usare cfqueryparam e uno dei tipi di data:cf_sql_date (solo data) o cf_sql_timestamp (data e ora).

  • Terzo, come ho detto su l'altro thread , devi davvero semplificare la tua richiesta! Che molte sottoquery siano già ingombranti .. l'aggiunta di filtri di data a ciascuna sottoquery lo rende decisamente ingestibile. Consiglierei di cercare modi per semplificarlo. Suggerimento di Ed ha offerto una possibilità, riducendola a un unico JOIN e alcune chiamate di funzione.

Bene, in realtà è proprio così che il tuo IDE viene visualizzato agli umani. Non è davvero memorizzato in questo modo. Internamente, le date vengono memorizzate come numeri grandi. Tuttavia, la tua query deve tenere conto del fatto che la tua colonna memorizza una data e volta.

Supponi di voler recuperare tutti i record datati a giugno:

    form.startDate = "06/01/2013"
    form.endDate = "06/30/2013"

Concettualmente, avresti bisogno di un'espressione sql come questa:

    WHERE column BETWEEN '06/01/2013 at midnight' AND '06/30/2013 11:59:59 PM' 

Tuttavia, la costruzione di quei valori di data/ora è un po' goffa IMO. Un modo più semplice per gestirlo è usare questo paradigma:

   WHERE column >= {startDateAtMidnight}        
   AND   column <  {dayAfterEndDateAtMidnight}

Il tuo filtro di query effettivo sarebbe simile a questo:

    WHERE column >= <cfqueryparam value="#form.startDate#" 
                                  cfsqltype="cf_sql_date">
    AND   column <  <cfqueryparam value="#dateAdd('d', 1, form.endDate)#" 
                                  cfsqltype="cf_sql_date">

Aggiungendo un giorno a form.endDate e utilizzando un < confronto, la query risultante è:

    WHERE column >= '2013-06-01 00:00:00'  
    AND   column < '2013-07-01 00:00:00'  

Ciò produrrà esattamente gli stessi risultati dell'espressione BETWEEN precedente.