2011-04-08 3 views
1

HI
Je tableaux ci-dessousrequête de jointure à la date Plage

========================= 
Periods 
========================= 
PeriodID StartDate EndDate 
1   01-01-11 07-01-11 
2   08-01-11 15-01-11 

et ainsi de suite pour l'année entière

========================= 
History 
========================= 
PersonID From  To 
1   01-01-11 05-04-11 
2   17-06-11 NULL 
and so on 

Je veux que la sortie suivante

StartDate EndDate PersonID 
    01-01-11 07-01-11 1 
    08-01-11 15-01-11 1 
    . 
    . 
    15-04-11 21-04-11  NULL 
    . 
    . 
    15-06-11 21-06-11  2 

Je dois prendre la jointure entre ces deux tables, mais je ne pouvais pas comprendre comment la condition de jointure sera ressembles

Ragards

+0

IS Histoire une relation Many to Many à la table utilisateur? – ysrb

+0

@ysrb pour une période, il n'y aura qu'une seule personne à la fois – Tassadaque

+0

OK laissez-moi l'essayer. une autre chose Dans la table d'historique, la date de début et la date de fin ne correspondent pas nécessairement à la table des périodes. Ces dates peuvent correspondre à n'importe quelle date de l'année – Tassadaque

Répondre

4
SELECT 
    p.StartDate, 
    p.EndDate, 
    h.PersonID 
FROM Periods p 
    LEFT JOIN History h 
    ON h.[From] BETWEEN p.StartDate AND p.EndDate OR 
     p.StartDate BETWEEN h.[From] AND ISNULL(h.[To], '30000101') 
1

Pouvez-vous s'il vous plaît essayer:

SELECT P.StartDate, P.EndDate, H.PersonID 
FROM Period P INNER JOIN History H ON P.StartDate <= H.Fromand (P.EndDate >= H.To OR H.To IS NULL) 

J'ai modifié le SQL après avoir lu la spécification plus clairement

J'ai modifié à nouveau le SQL. J'utilise INNER JOIN maintenant.

+0

Il montre le même ID de personne = 1 pour tous les enregistrements – Tassadaque

+0

il ne peut pas être une jointure interne car il doit afficher la période même s'il n'y a aucune entrée d'historique pour cette période (voir ligne 5 de la sortie) – clyc

1

Il aurait une incidence sur la performance, mais je pense qu'il vaut la peine d'essayer juste le bizarre à la recherche entre:

select x 
from table1 t1 
    inner join table2 t2 
    on t2.date between t1.startdate and t1.enddate 

Que cela fonctionne ou non dépendra que ce soit pour être la production, ou tout simplement une chose de temps , et combien de disques sont impliqués. C'est peut-être trop lent.

1

Vous devez effectuer une jointure à gauche pour afficher toutes les périodes disponibles, même si aucune entrée d'historique n'est associée à cette période. Les critères seraient si la date de l'historique était entre la période. Vous devez également vérifier si le jour était nulle et l'inclure dans vos résultats

SELECT p.StartDate, p.EndDate, h.PersonId 
FROM Period p 
     LEFT JOIN History h 
      ON p.StartDate >= h.[From] AND 
      (h.[To] IS NULL OR p.EndDate <= h.[To]) 
+0

retourne tous les enregistrements à partir de la période comme attendu il montre personid = 1 correctement mais où personID = 2 devrait être montré il montre null – Tassadaque

+0

p.EndDate IS NULL devrait être h.EndDate Ai-je raison? Quand je change cela, je manque une période qui est de l'ordre de 17-06-11 – Tassadaque

+0

@Tassadaque J'ai eu une faute de frappe là-dedans. il n'aurait pas dû vérifier que le p.EndDate était nul, mais aurait dû vérifier si la colonne h. [To] était nulle. – clyc

-1

à table « histoire », NULL mis « 9999-12-31 »

select * à partir de périodes une histoire de jointure interne b sur a.from < b.to et a.to> b.from

+1

Non !!! C'est un hack très laid et non portable. Explicitement tester pour 'NULL' à la place. – RandomSeed