Eventi, Sql, date, …

Stavo lavorando ad una applicazione Web che deve gestire gli eventi, per intenderci delle news che si verificano per un certa durata definiti da una data iniziale e da una data finale.

Il mio problema era quello di selezionare tutti gli eventi che si verificano in un determinato intervallo, in questo caso avevo a disposizione quattro date:

  • dataInizioEvento;
  • dataFineEvento;
  • dataInizioPeriodo;
  • dataFinePeriodo.

Il mio obbiettivo era quello di dovere selezionare gli eventi che ricadeveno nel periodo richiesto dall’utente, il problema era come faccio a rappresentare questa condizione, dopo un suggerimento di Luca di rappresentare le date e di conseguenza le varie possibilità su delle linee temporali ottenendo come risultato quello mostrato nella figura 1.

Figura 1
                                Figura 1 [1]

Dall’immagine si capisce che si possono verificare sei casi di cui quattro (quelli indicati con la “V” sono quelli validi) analizzando l’immagine si nota subito qual’è la relazione che determina quali sono gli eventi validi:

max(D1, T1) ≤ min(D2, T2)

A questo punto il problema è risolto o almeno così sembra. A questo punto il problema diventa come rappresentare quell’espressione con una query in T-SQL, dopo aver fatto diversi tentativi sono arrivato alla conclusione che non sarei mai riuscito a rappresentare quell’espressione in T-SQL, quindi non avevo concluso nulla Angry.

Dopo aver perso ulteriore tempo e pazienza dietro prove e condizioni assurde, ho provato a ricavarmi la condizione da inserire nella query partendo dai casi non validi.

I casi in cui non si verifica l’evento sono due:

il primo se D2 < T1

il secondo se T2 < D1

a questo punto la condizione che verifica se si tratta di un evento non valido e quella che segue:

(D2 < T1) OR (T2 < D1)

Arrivati a questo punto per ottenere la condizione che verifica se si tratta di un evento valido o meno basta negare la condizione precedente ottenendo questo risultato:

(NOT (D2 < T1) OR (T2 < D1)).

La condizione che ci siamo ricavati può essere inserita nella query nel caso in cui ne vogliamo una più semplice e lineare bisogna modificare la condizione utilizzando le Leggi di De Morgan [2] ottenendo questa condizione

(T1 ≤ D2) AND (D1 ≤ T2).

A questo punto possiamo scrivere la nostra query, in questo caso mi baserò su di una tabella Eventi come quella presentata in figura 2.

 

TabellaEventi
                                            Figura 2.

 

Si ottiene la query:

DECLARE @DataInizioPeriodo AS DATETIME;
DECLARE @DataFinePeriodo AS DATETIME;
SET @DataInizioPeriodo = '20080501';
SET @DataFinePeriodo = '20080531';
SELECT IdEvento, NomeEvento, DataInizioEvento, DataFineEvento FROM Eventi 
WHERE (@DataInizioPeriodo <= DataInizioEvento) AND (@DataFinePeriodo >= DataFineEvento);

&#a160;

Saluto e ringrazio mio fratello per la realizzazione delle immagini e per il supporto grafico. A questo indirizzo potete scaricarvi una versione simpatica dello schema delle date degli eventi, sull’asse temporale.

[1]
D1 rappresenta la data iniziale dell’evento;
D2 rappresenta la data finale dell’evento;
T1 rappresenta la data iniziale del periodo impostato dall’utente;
T2 rappresenta la data finale del periodo impostato dall’utente.

[2]
NOT (p AND q) = (NOT p) OR  (NOT q)
NOT (p OR  q) = (NOT p) AND (NOT q)

Published Tuesday, June 03, 2008 7:50 AM by MADIL
Filed under:
Powered by Community Server (Commercial Edition), by Telligent Systems