PARTE SECONDA Riepilogo Parte Prima. Abbiamo visto le caratteristiche dei campi in formato data/ora di MySQL. MySQL e' molto flessibile nella gestione delle date. Permette di copiare, inserire calcolare anche al di fuori del formato date/time. Molta flessibilita' significa piu' controllo delle congruenze per il softwerista. Un formato errato si tradurra' in una sequenza di zeri. Se questo formato errato lo inserite, in un campo con formato INT, char/varchar questo verra' scritto, ma continuera' ad essere un formato errato e quindi inservibile alle funzioni MySQL. Da notare inoltre, che ogni formato ha un diverso range di validita', e' possibile copiare, calcolare dati tra un campo e l'altro mantenendo i valori iniziali, ma la congruenza del range e/o del tipo di formato la dovrete fare voi. Se non sara' corretto, MySQL non segnalera' errori, ma mettera' semplicemente una bella serie di zeri al posto di... MySQL possiede una buona scelta di funzioni date/time che e' possibile utilizzare nelle query alle sezioni INSERT, UPDATE, SELECT e WHERE. Un primo gruppo rappresenta le funzioni che rendono la data e/o l'ora senza alcuna manipolazione dei dati e con argomento della funzione = VOID. A)Funzioni di MySQL per l'estrazione di dati DATE/TIME (VOID). NOW() SYSDATE() CURRENT_TIMESTAMP Sono in pratica equivalenti. Vediamo, estensibili a tutti, le caratteristiche di NOW() che e' presente nel menu' PhpMyAdmin. La funzione NOW() acquisisce data/ora di sistema una sola volta all'inizio della query, quindi il valore ottenuto verra' utilizzato per soddisfare tutte le richieste della query stessa. Aggiorna automaticamente un solo campo formato TIMESTAMP, il primo in ordine di posizione nella lista dei campi della tabella. Gli altri campi presenti nello stesso record con formato TIMESTAMP verranno aggiornati solo su esplicita richiesta della query. Le tre funzioni sopra elencate, rendono sempre data/ora secondo il seguente formato: 'YYYY-MM-DD HH:MM:SS' frm. stringa oppure YYYYMMDDHHMMSS frm. numerico. La forma dipendera' dal tipo di campo che ricevera' il dato. E' possibile forzare un formato numerico nella risposta sommando uno zero oppure moltiplicando * 1 la data richiesta. Se il campo non e' dimensionato a sufficienza oppure e' un campo con dati TIME o DATE i dati superflui o eccedenti il campo verranno persi. Fa eccezione il formato TIMESTAMP, come visto nella parte prima, che conserva sempre tutti i dati inseriti. SELECT NOW() => 2003-05-20 17:29:09 SELECT NOW() + 0 => 20030520190137 Forzare una risposta numerica SELECT * FROM tabella WHERE nome_campo = NOW() UPDATE tabella SET data=NOW() where data < NOW() Aggiorna ad oggi un campo data. UPDATE tabella SET scadenza = data + INTERVAL 1 MONTH WHERE id = $id. Mettera' nel campo 'scadenza' la data memorizzata nel campo 'data' + un mese DELETE FROM tabella where scadenza < NOW() Cancella record scaduti CURRENT_DATE - CURDATE() CURRENT_TIME - CURTIME() Queste 4 (anzi 2) funzioni forniscono rispettivamente solo la data, e solo l'ora. Sono i fratelli minori delle funzioni viste prima. Vengono utilizzati quando serve avere o solo la data oppure soltanto l'ora. SELECT CURDATE() => 2003-05-20 abbiamo la data senza l'ora. SELECT CURTIME() => 22:19:50 abbiamo l'ora senza la data. SELECT CURDATE() + 0 => 20030520 data senza ora in formato numerico. SELECT CURTIME() * 1 => 221950 ora senza data in formato numerico. B)Funzioni di MySQL per l'estrazione mirata di dati DATE/TIME. Vediamo quali sono, a che servono e qualche esempio di applicazione. 1) - Informazioni sul giorno. Se abbiamo bisogno di estrarre un giorno da una data, abbiamo disponibili ben 4 specifiche funzioni: DAYOFYEAR(data) DAYOFMONTH(data) DAYOFWEEK(data) WEEKDAY(data) DAYOFYEAR - Da come risultato in formato numerico, il giorno dell'anno estraendolo da una data . Cioe' rende il numero dei giorni passati a partire dal 1 Gennaio di un determinato anno. funziona cosi': SELECT DAYOFYEAR("2003-05-20") => 140 140° giorno dell'anno 2003 SELECT DAYOFYEAR("2000/05/20") => 141 141° nel 2000 perche' bisestile. SELECT DAYOFYEAR("20030520") => 140 140° giorno dell'anno 2003 SELECT DAYOFYEAR("00-05-20") => 141 141° giorno dell'anno 2000 SELECT DAYOFYEAR(NOW()) => 140 140° alla data del 20-05-2003 SELECT DAYOFYEAR(CURDATE()) => 140 140° giorno dell'anno 2003 SELECT DAYOFYEAR(nome_campo) from tabella dove nome_campo contiene una data valida ma non cosi', anche se la query non dara' segnalazioni di errore: SELECT DAYOFYEAR("20-05-2003") as data => 141 interpreta 2020-05-20(03 eccedenti) SELECT DAYOFYEAR(CURTIME()) => NULL Perche' CURTIME contiene solo l'ora. SELECT DAYOFYEAR(2003-05-20) => NULL Perche' mancano gli apici all'argomento. Negli esempi che seguiranno si alterneranno le varie forme possibili di inserimento della data da analizzare. Si tenga presente che le regole sopra esposte sono applicabili per tutte le funzioni che vedremo. DAYOFMONTH - Da come risultato in formato numerico, il giorno del mese estraendolo da una data. Cioe' rende il numero dei giorni passati a partire dal giorno 1 di un determinato mese. SELECT DAYOFMONTH("2003-05-20") => 20 20° giorno del mese di Maggio/2003 DAYOFWEEK - Da come risultato in formato numerico, il giorno della settimana estraendolo da una data. L'indice dei giorni che viene fornito e' conforme allo standard ODBC. L'indice inizia con: 1 = domenica, 2 = lunedi', 3 = martedi'.... ecc. SELECT DAYOFWEEK("2003-05-20") => 3 martedi' 3° giorno della settimana SELECT * FROM order WHERE dayofweek(data_order)=2; =>Gli ordini del lunedì. WEEKDAY - E molto simile a DAYOFWEEK ma rende un indice diverso per i giorni della settimana, sempre estratti da una data: 0 = Lunedi', 1= martedi',2 = martedi', 3= mercoledi' ....ecc. SELECT WEEKDAY("2003-05-20") => 1 indice 1 del giorno martedi' 2) Estrazione Anni, Trimestri, Mesi, Settimane. Nome dei mesi e giorni. Anche queste funzioni lavorano a partire da una data. Data, ricordiamo, in qualsiasi formato ammesso. YEAR(date) QUARTER(date) MONTH(date) WEEK(date[, primogiorno]) YEARWEEK(date[,primogiorno] MONTHNAME(date) DAYNAME(date) YEAR(date) - Estrae l'anno da una data in formato numerico di 4 digit. SELECT YEAR(NOW()); 2003 Anno corrente. SELECT * FROM tabella WHERE YEAR(campo_data) < 2003 QUARTER(date) - Rende il n. del trimestre da una data inserita. Valori: 1=I° trimestre, 2=secondo, 3=terzo, 4=quarto. SELECT QUARTER(NOW()); => 2 Secondo TRIMESTRE 2003. SELECT * FROM tabella where QUARTER(campo_data) = 2 AND YEAR(campo_data)= 2003; Rendera' tutti i record con data inserita nel II trimestre 2003. MONTH(date) - Da come risultato il n. del mese estratto da una data, nell'intervallo 1-12. SELECT MONTH(NOW()); => 5 n. del mese di maggio. SELECT * FROM tabella WHERE MONTH(campo_data) = 5 AND YEAR(campo_data)= 2003; Rendera' tutti i record con data inserita nel maggio 2003. WEEK(date) - YEARWEEK(date) - Queste due funzioni rendono il numero della settimana da una data dell'anno. Il secondo parametro "first" serve ad indicare se la settimana inizia di domenica (0) oppure Lunedi'(1). Il comportamento differisce nel modo di presentare i dati. WEEK() ha un range 0-53 dove la settimana 0 sara' nei giorni che intercorrono dal giorno 1 Gennaio alla prima ricorrenza della domenica o lunedi' (dipende dalla scelta 0/1). YEARWEEK() invece rende anno e n. settimana in forma numerica. Il range delle settimane e' 1-52. Vediamo alcuni confronti: Il giorno 2000-01-01 era un sabato. select week("2000-01-01") => 0 -> settimana 0 (sabato) select week("2000-01-02") => 1 -> settimana 1 (domenica) select week("2000-01-02","1") => 0 -> settimana 0 (domenica) select week("2000-01-03","1") => 1 -> [i]settimana 1 (lunedi') select yearweek("2000-01-01") => 199952 -> Anno 1999 settimana 52 (sabato) select yearweek("2000-01-02") => 200001 -> Anno 2000 settimana 01 (domenica) select yearweek("2000-01-02","1") => 199952 -> Anno 1999 settimana 52 (domenica) select yearweek("2000-01-03","1") => 200001 -> Anno 2000 settimana 01 (lunedi') Si pone l'accento su queste funzioni perche' il numero della settimana e' molto usato nelle applicazioni aziendali (statistiche, pert, contabilita'...). Le agende in circolazione inoltre non rispondono ad un unico standard. Sicuramente la funzione YEARWEEK() non lascia adito a dubbi (no 0 - no 53). MONTHNAME - DAYNAME - Queste due funzioni estraggono i nomi del mese e del giorno da una data. Peccato siano in inglese. Si puo' facilmente convertire in italiano con una breve funzione PHP che vedremo in seguito: SELECT MONTHNAME(NOW()) as mese => May SELECT DAYNAME("2003-05-20") as giorno => Tuesday 3) Estrazione di Ore, Minuti, Secondi. HOUR(time) - MINUTE(time) - SECOND(time) - Queste funzioni estraggono ore, minuti, secondi a partire da un dato che abbia nel contenuto ore, minuti secondi. Puo' essere quindi un campo o funzione con dati tipo TIMESTAMP o DATETIME o TIME. Ovviamente non potra' essere un campo con dati in formato YEAR o DATE. SELECT HOUR(CURTIME()) as hour, MINUTE(CURTIME()) as min, SECOND(CURTIME()) as sec; ed ecco l'equivalente di una funzione EXPLODE() con ora, minuti e secondi. Pag 2 - SEGUE ... Bibliografia: http://www.mysql.com/doc/en/index.html