web-dev-qa-db-fra.com

Requête MySQL pour sélectionner des événements entre les dates de début et de fin

J'ai une table MySQL nommée «événements» qui contient des données d'événement. Les colonnes importantes sont 'start' et 'end' qui contiennent une chaîne (AAAA-MM-JJ) pour représenter le début et la fin des événements.

Je veux obtenir les enregistrements de tous les événements actifs d'une période donnée.

Événements:

------------------------------
ID | DÉBUT | FIN | 
 ------------------------------ 
 1 | 2013-06-14 | 2013-06-14 | 
 2 | 2013-06-15 | 2013-08-21 | 
 3 | 2013-06-22 | 2013-06-25 | 
 4 | 2013-07-01 | 2013-07-10 | 
 5 | 2013-07-30 | 2013-07-31 | 
------------------------------

Demande/recherche:

Exemple: Tous les événements survenus entre 2013-06-13 et 2013-07-22: N ° 1, N ° 3, N ° 4 

 Les événements SELECT id from WHERE commencent entre '2013-06-13' ET '2013-07 -22 ': N ° 1, N ° 2, N ° 3, N ° 4 
 Sélectionnez id parmi les événements WHERE se terminant entre' 2013-06-13 'ET' 2013-07-22 ': N ° 1, N ° 3, N ° 4 __. ====> intersecter: # 1, # 3, # 4
Exemple: Tous les événements survenus entre le 2013-06-14 et le 2013-06-14: 

 Les événements SELECT id de FROM où commencent entre '2013-06-14' ET '2013-06-14': # 1 
SELECT id FROM events WHERE se termine entre '2013-06-14' ET '2013-06-14': # 1 
 ====> intersecter: # 1

J'ai essayé de nombreuses requêtes mais je n'arrive toujours pas à obtenir la requête SQL exacte.

Tu ne sais pas comment faire ça? Aucune suggestion?

Merci!

9
Guicara

Si j'ai bien compris, vous essayez d'utiliser une seule requête, je pense que vous pouvez simplement fusionner votre recherche de date dans des clauses WHERE

SELECT id 
FROM events 
WHERE start BETWEEN '2013-06-13' AND '2013-07-22' 
AND end BETWEEN '2013-06-13' AND '2013-07-22'

ou encore plus simplement, vous pouvez simplement utiliser les deux colonnes pour définir le filtre de temps de recherche

SELECT id 
FROM events 
WHERE start >= '2013-07-22' AND end <= '2013-06-13'
17
Fabio

Vous avez besoin des événements qui commencent et finissent dans la portée. Mais ce n'est pas tout: vous voulez aussi les événements qui commencent dans la portée et les événements qui se terminent dans la portée. Mais vous n'êtes toujours pas là car vous souhaitez également que les événements commencent avant la portée et se terminent après la portée.

Simplifié:

  1. événements avec une date de début dans la portée 
  2. événements avec une date de fin dans le champ d'application 
  3. événements avec la portée startdate entre startdate et enddate

Comme le point 2 produit des enregistrements qui répondent également à la requête du point 3, nous n’aurons besoin que des points 1 et 3.

Donc le SQL devient:

SELECT * FROM events 
WHERE start BETWEEN '2014-09-01' AND '2014-10-13' 
OR '2014-09-01' BETWEEN start AND end
11
Peter de Groot

Ici beaucoup de bonne réponse mais je pense que cela aidera quelqu'un 

select id  from campaign where ( NOW() BETWEEN start_date AND end_date) 
6
SELECT id
FROM events
WHERE start <= '2013-07-22'
AND end >= '2013-06-13';

Ou utilisez MIN() et MAX() si vous ne connaissez pas la priorité.

3
Olivier Coilland

Je suppose que les événements actifs dans une période de temps signifie qu'au moins un jour de l'événement tombe dans la période de temps. Il s’agit d’un simple problème de "recherche de dates qui se chevauchent" et il existe une solution générique:

-- [@d1, @d2] is the date range to check against
SELECT * FROM events WHERE @d2 >= start AND end >= @d1

Quelques tests:

-- list of events
SELECT * FROM events;
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    1 | 2013-06-14 | 2013-06-14 |
|    2 | 2013-06-15 | 2013-08-21 |
|    3 | 2013-06-22 | 2013-06-25 |
|    4 | 2013-07-01 | 2013-07-10 |
|    5 | 2013-07-30 | 2013-07-31 |
+------+------------+------------+

-- events between [2013-06-01, 2013-06-15]
SELECT * FROM events WHERE '2013-06-15' >= start AND end >= '2013-06-01';
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    1 | 2013-06-14 | 2013-06-14 |
|    2 | 2013-06-15 | 2013-08-21 |
+------+------------+------------+

-- events between [2013-06-16, 2013-06-30]
SELECT * FROM events WHERE '2013-06-30' >= start AND end >= '2013-06-16';
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    2 | 2013-06-15 | 2013-08-21 |
|    3 | 2013-06-22 | 2013-06-25 |
+------+------------+------------+

-- events between [2013-07-01, 2013-07-01]
SELECT * FROM events WHERE '2013-07-01' >= start AND end >= '2013-07-01';
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    2 | 2013-06-15 | 2013-08-21 |
|    4 | 2013-07-01 | 2013-07-10 |
+------+------------+------------+

-- events between [2013-07-11, 2013-07-29]
SELECT * FROM events WHERE '2013-07-29' >= start AND end >= '2013-07-11';
+------+------------+------------+
| id   | start      | end        |
+------+------------+------------+
|    2 | 2013-06-15 | 2013-08-21 |
+------+------------+------------+
2
Salman A
SELECT * 
FROM events 
WHERE start <= '2013-07-22' OR end >= '2013-06-13'
1
Philip Sheard

Si vous souhaitez utiliser l'option INTERSECT, le code SQL est le suivant

(SELECT id FROM events WHERE start BETWEEN '2013-06-13' AND '2013-07-22') 
INTERSECT
(SELECT id FROM events WHERE end BETWEEN '2013-06-13' AND '2013-07-22') 
0
bkm

essaye ça

    SELECT id FROM events WHERE start BETWEEN '2013-06-13' AND '2013-07-22' 
                          AND   end   BETWEEN '2013-06-13' AND '2013-07-22'

DEMO ICI

sortie:

 ID
 1
 3
 4
0
echo_Me

EDIT: J'ai beaucoup serré le filtre. Je ne pouvais pas comprendre pourquoi avant de m'assurer que quelque chose se passe bien dans la période. C'est ceci: Date de début AVANT la fin de la période et Date de fin après le début de la période.

Avec l'aide de quelqu'un dans mon bureau, je pense que nous avons compris comment inclure tout le monde dans le filtre. Il existe 5 scénarios dans lesquels un élève serait considéré comme actif pendant la période en question: 

1) L'élève a commencé et s'est terminé au cours de cette période.

2) L'élève a commencé avant et s'est terminé au cours de la période.

3) L'élève a commencé avant et s'est terminé après la période.

4) L'élève a commencé pendant la période et s'est terminé après la période.

5) L'élève a commencé pendant la période et est toujours actif (n'a pas encore de date de fin)

Sur la base de ces critères, nous pouvons condenser les déclarations en quelques groupes, car un étudiant ne peut se terminer qu'entre les dates de la période, après la date de la période, ou sans date de fin:

1) L'élève se termine pendant la période ET [l'élève commence avant OR pendant]

2) L'élève se termine après la période ET [l'élève commence avant OR pendant]

3) L'élève n'a pas encore fini ET [l'élève commence avant OR pendant]

   (
        (
         student_programs.END_DATE  >=  '07/01/2017 00:0:0'
         OR
         student_programs.END_DATE  Is Null  
        )
        AND
        student_programs.START_DATE  <=  '06/30/2018 23:59:59'
   )

Je pense que cela couvre finalement toutes les bases et inclut tous les scénarios dans lesquels un étudiant, un événement ou quoi que ce soit est actif pendant une période de temps où vous ne disposez que d'une date de début et d'une date de fin. S'il vous plaît, n'hésitez pas à me dire qu'il me manque quelque chose. Je veux que ce soit parfait pour que les autres puissent l'utiliser, car je ne crois pas que les autres réponses ont tout bien compris.

0
Lord Bobbymort