2009-10-13 5 views
1

Je ne suis pas sûr de la terminologie ici, alors laissez-moi donner un exemple. J'ai cette requête:Rejoindre la table dérivée

SELECT * FROM Events 
-------------------- 

Id Name  StartPeriodId EndPeriodId 
1 MyEvent 34    32 

Ici, les PeriodIds préciser combien de temps l'événement dure, penser comme semaines de l'année indiquée dans une autre table si cela aide. Notez que EndPeriodId n'est pas nécessairement séquentiel après le StartPeriodId. Alors que je pouvais faire ceci:

SELECT * FROM Periods WHERE Id = 34 
----------------------------------- 

Id StartDate EndDate 
34 2009-06-01 2009-08-01 

S'il vous plaît ne vous attardez pas sur cette structure, car il est seulement un exemple et non comment cela fonctionne réellement. Ce que je dois faire est de venir avec ce jeu de résultats:

Id Name PeriodId 
1 MyEvent 34 
1 MyEvent 33 
1 MyEvent 32 

En d'autres termes, je dois sélectionner une ligne d'événement pour chaque période où l'événement existe. Je peux facilement calculer les informations de période (32, 33, 34), mais mon problème consiste à les extraire en une seule requête.

C'est dans SQL Server 2008.

Répondre

3

Je peux me tromper, et je ne peux pas tester en ce moment parce qu'il n'y a pas de SQL Server disponible en ce moment, mais je pas simplement:

SELECT  Events.Id, Events.Name, Periods.PeriodId 
FROM  Periods 
INNER JOIN Events 
ON   Periods.ID BETWEEN Events.StartPeriodId AND Events.EndPeriodId 
+0

Pas exactement, car comme je le disais dans la question, « avis que le EndPeriodId est séquentiellement pas nécessairement après la StartPeriodId ». Cela signifie que vous ne pouvez pas compter sur BETWEEN et devez regarder les dates réelles des périodes. –

+0

On dirait que je peux utiliser quelque chose de similaire, je vérifie juste! –

+0

Je t'aime Maximilian Mayerl. –

0

Je suppose que vous voulez une liste de toutes les périodes qui tombent entre les dates pour les périodes spécifiées par les ID de période de début/fin.

With CTE_PeriodDate (ID, MaxDate, MinDate) 
as (
Select Id, Max(Dates) MaxDate, MinDate=Min(Dates) from (
Select e.ID, StartDate as Dates from Events e 
Inner join Periods P on P.ID=StartPeriodID 
Union All 
Select e.ID, EndDate from Events e 
Inner join Periods P on P.ID=StartPeriodID 
Union All 
Select e.ID, StartDate from Events e 
Inner join Periods P on P.ID=EndPeriodID 
Union All 
Select e.ID, EndDate from Events e 
Inner join Periods P on P.ID=EndPeriodID) as A 
group by ID) 
Select E.Name, P.ID from CTE_PeriodDate CTE 
Inner Join Periods p on 
(P.StartDate>=MinDate and P.StartDate<=MaxDate) 
and (p.EndDate<=MaxDate and P.EndDate>=MinDate) 
Inner Join Events E on E.ID=CTE.ID 

Ce n'est pas la meilleure façon de procéder, mais cela fonctionne. Il obtient les plages de dates min et max pour les périodes spécifiées sur l'événement. En utilisant ces deux dates, il se joint à la table de périodes sur les valeurs situées dans la plage entre les deux.

Kris