54 votes

Détecter les plages de dates qui se chevauchent dans une même table

J'ai un tableau avec les données suivantes

PKey  Start       End         Type
====  =====       ===         ====
01    01/01/2010  14/01/2010  S
02    15/01/2010  31/01/2010  S
03    05/01/2010  06/01/2010  A

Et je veux obtenir les résultats suivants

PKey  Start       End         Type
====  =====       ===         ====
01    01/01/2010  14/01/2010  S
03    05/01/2010  06/01/2010  A

Des idées pour commencer ? Une grande partie de la lecture que j'ai faite suggère que je dois créer des entrées pour chaque jour et les joindre les jours correspondants, est-ce la seule façon ?

0 votes

01 ne se chevauche pas 02 . Pourquoi voudriez-vous vous débarrasser de 02 ?

0 votes

J'ai compris que cela signifiait : sélectionner les lignes où l'intervalle défini dans la ligne chevauche tout intervalle défini dans d'autres lignes.

0 votes

Je cherche des enregistrements qui se chevauchent entre les types S et A.

2voto

Dmitry Polushkin Points 920

Dans MySQL, vous avez essentiellement besoin :

SELECT COUNT(*) FROM date_ranges AS A, date_ranges AS B WHERE A.id <> B.id AND A.id > B.id AND A.end_at > B.start_at AND B.end_at > A.start_at

> dans la deuxième et la troisième déclaration peuvent être remplacées par >= à suivre comprend la correspondance.

Ce sujet est lié à "Allen's Interval Algebra" et il y a quelques lectures supplémentaires sur ce sujet qui peuvent être trouvées par ces liens :

1voto

fujiiface Points 42

Nous avons tous besoin de ce type de prédicat de chevauchement dans nos requêtes depuis un certain temps et je pense avoir trouvé une solution très simple. aquí .

Dans mon application, par exemple, j'ai des polices qui ont le même numéro de police mais dont la description change d'une année fiscale à l'autre. Lorsqu'un utilisateur saisit un nouvel enregistrement (même numéro de police, description de police différente), j'avais besoin d'un moyen de savoir si cette police existe déjà pour la période spécifiée. Si les nouvelles dates d'entrée en vigueur et d'expiration de la police se chevauchent avec celles qui figurent déjà dans la base de données, je devais émettre un message d'erreur et indiquer à l'utilisateur pourquoi sa saisie n'était pas correcte.

Pour ce faire, j'ai utilisé l'énoncé de prédicat suivant :

AND @_expiration >= EffectiveDate AND ExpirationDate >= @_effective

J'espère que quelqu'un d'autre trouvera cela aussi utile que moi.

1voto

Eminem Points 11

J'ai dû faire quelque chose de très similaire pour empêcher les vacances en double d'être saisies dans une table. C'était dans Access et écrit dans un temptable sur l'entrée donc j'ai dû l'interroger en VBA SQL :

 stCommandText = "SELECT " _
                    & "* " _
                    & "FROM " _
                    & "TableName a, " _
                    & "TableName b " _
                    & "WHERE " _
                    & "a.ID = b.ID " _
                    & "AND a.Startdate >= b.Startdate AND a.StartDate <= b.EndDate " _
                    & "AND a.AutoNo <> b.AutoNo "

0voto

ozmike Points 583

BTW - Si vous n'avez pas d'identifiant unique, par rapport à vos dates, vous pouvez le faire avec oracle FYI

with date_ranges
as
(
SELECT 
     rownum as pkey,
    date_ranges.*
FROM  date_ranges
) 
select 
dr1.* 
from 
date_ranges dr1 , date_ranges dr2
where  dr1.pkey > dr2.pkey
AND dr1.end_dt >= dr2.start_dt 
AND dr2.end_dt >= dr1.start_dt

0voto

kuldeep Points 218

Sql='SELECT task_id , task_start_date , task_due_date FROM ( wba_task ) WHERE ( task_start_date <="2016-07-13" ET task_due_date >= "2016-07-25") OU ( task_due_date ENTRE "2016-07-13" et "2016-07-25")' ;

La requête de Codeigniter est ci-dessous.

$fromdaysDate="2016-07-13";//changed date
$todaysDate="2016-07-25";//changed date
$this->db->select('task_id,task_start_date, task_due_date'); 
$this->db->where('task_start_date <="'.date('Y-m-d', strtotime($fromdaysDate)).'"');
$this->db->where('task_due_date >="'.date('Y-m-d', strtotime($todaysDate)).'"');    
$this->db->or_where('task_due_date BETWEEN "'. date('Y-m-d', strtotime($fromdaysDate)). '" and "'. date('Y-m-d', strtotime($todaysDate)).'"');   
$alltask=$this->db->get('wba_task')->result_array();
echo $this->db->last_query();

récupérer toutes les données de chevauchement de la base de données.... enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X