2010-05-03 10 views
3

Je sais qu'il y a beaucoup de ces types de questions, mais je n'en ai pas vu de suffisamment similaire à mes critères. Donc, je voudrais demander votre aide s'il vous plaît. Les champs que j'ai sont juste début et fin qui sont des types de temps. Je ne peux pas impliquer de dates spécifiques dans ceci. Si les plages horaires ne vont pas passer minuit à travers jour, je venais de comparer deux tuples en tant que tel:Les chevauchements SQL de temps passent minuit (sur 2 jours)

end1 > start2 AND start1 < end2 

(. Points d'extrémité touchant ne sont pas considérés chevauchaient ici)

Mais quand j'impliquons le temps gamme qui passe (ou à) minuit, cela ne fonctionne évidemment pas. Par exemple, donné:

start | end 
--------+-------- 
06:00PM | 01:00AM 
03:00PM | 09:00PM 

Sans les dates, comment puis-je y parvenir, s'il vous plaît. Ma supposition est, si la fin est moins que le début, alors nous impliquons 2 jours.

J'essaie de le faire en langage SQL standard, donc juste une logique simple et concise dans la clause WHERE.

Merci à tous!


Ajouté:

Aussi, comment pourrais-je tester si une plage de temps enveloppe complètement une autre? Merci encore!

+1

@janechii: Bienvenue dans StackOverflow! Vous pouvez améliorer votre question en éditant les balises pour refléter la base de données que vous utilisez ('oracle',' mysql', 'sql-server', ...) –

+0

@janechii - Pouvez-vous montrer aussi utiliser un peu du schéma de la table ? – Thomas

+0

@Peter - Merci. J'utilise spécifiquement postgresql, mais j'aimerais le faire fonctionner dans d'autres bases de données, s'il-vous-plaît. – janechii

Répondre

2

Si votre SQL prend en charge les différences de temps:

(end1 - start1) > (start2 - start1) AND (end2 - start2) > (start1 - start2) 
+0

oh c'est chouette, merci! La logique veut-elle que la différence des heures de départ soit supérieure à la durée? – janechii

+0

durée devrait toujours être un nombre positif, cependant, je pense. donc: abs (fin1 - début1)> (début2 - début1) ET abs (fin2 - début2)> (début1 - début2) – janechii

+0

C'est un peu chouette!La dérivation est venue à moi par l'algèbre plutôt que par l'intuition: prenez votre expression, et soustrayez start1 des deux côtés de la comparaison sur la gauche, et soustrayez start2 des deux côtés sur la droite. Cela se traduit par: la durée de event1 doit dépasser le temps entre le début de event1 et le début de event2, et la durée de event2 doit dépasser le temps entre le début de event2 et le début de event1. La symétrie est agréable. –

0

utilisation heure de début et la durée (en minutes ou quelle que soit l'unité appropriée)

1

Malheureusement, SQL « ordinaire » sera trop général à utiliser contre une base de données réelle. La raison en est que les différents produits de base de données ont différents niveaux de support pour calculer la durée entre deux temps. Par exemple, dans SQL Server 2008, il serait beaucoup plus simple de convertir les valeurs temporelles en DateTime, puis de faire la comparaison car de nombreux opérateurs de comparaison ne sont pas pris en charge sur le type de données Heure.

Select ... 
From (
     Select Cast(T.Start1 As DateTime) As Start1 
      , Case 
       When Cast(T.Start1 As DateTime) > Cast(T.End1 As DateTime) Then DateAdd(d,1,Cast(T.End1 As DateTime)) 
       Else Cast(T.End1 As DateTime) 
       End As End1 
     From ... 
     ) As T 
Where T.End1 > T2.Start2 And T1.Start2 < T2.End2    
+0

Oui, vous avez raison, la gestion de la date et l'heure semble différer beaucoup entre les bases de données. J'utilise PostgreSQL spécifiquement, mais cette solution est une solution intelligente qui devrait aussi fonctionner dans PG. Je vous remercie! – janechii

0

Le programme Transtar a rencontré ce problème. Les données temporelles n'étaient associées à aucune date et les données temporelles n'étaient pas dans un champ de date et d'heure. Initialement, le programme était conçu pour émettre des itinéraires de transit d'environ 4 heures du matin à minuit, ce qui fonctionnait bien tant que le transit n'était pas disponible 24 heures sur 24. J'ai construit une fonction qui a fait un test de glisse pour les temps de sorte que si vous avez demandé 5 heures, il regarderait des heures de 1h à 12h59. Je l'ai écrit en FORTRAN, mais l'algorythme serait le même indépendamment de la langue.

+0

Merci pour la suggestion, Dave! J'avais joué avec cette idée, mais cela semble déroutant pour les autres mainteneurs. Pour un système existant, c'est une bonne solution. – janechii

+0

convenu - très confus - la principale chose qui doit être réalisé est le temps de données est modulaire et le temps réel ne l'est pas. – Dave