代码之家  ›  专栏  ›  技术社区  ›  Colin Ramsay

根据派生表联接

  •  1
  • Colin Ramsay  · 技术社区  · 15 年前

    我不确定这里的术语,所以让我举个例子。我有这个问题:

    SELECT * FROM Events
    --------------------
    
    Id  Name     StartPeriodId  EndPeriodId
    1   MyEvent  34             32
    

    在这里,PeriodID指定事件持续的时间,如果这有帮助的话,可以将其视为另一个表中指定的一年中的几周。请注意,endPeriodID不一定在startPeriodID之后按顺序排列。所以我可以这样做:

    SELECT * FROM Periods WHERE Id = 34
    -----------------------------------
    
    Id StartDate   EndDate
    34 2009-06-01  2009-08-01
    

    请不要停留在这个结构上,因为它只是一个例子,而不是它的实际工作方式。我需要做的是得出这个结果集:

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

    换句话说,我需要为事件存在的每个期间选择一个事件行。我可以很容易地计算周期信息(32、33、34),但我的问题在于只在一个查询中提取它。

    这在SQL Server 2008中。

    2 回复  |  直到 15 年前
        1
  •  3
  •   Maximilian Mayerl    15 年前

    我可能错了,现在不能测试它,因为现在没有可用的SQL Server,但这不是简单的:

    SELECT      Events.Id, Events.Name, Periods.PeriodId
    FROM        Periods
    INNER JOIN  Events
    ON          Periods.ID BETWEEN Events.StartPeriodId AND Events.EndPeriodId
    
        2
  •  0
  •   KSimons    15 年前

    我假设您希望列出所有介于由开始/结束期间ID指定的期间的日期之间的期间。

    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
    

    这不是最好的方法,但确实有效。 它得到事件指定期间的最小和最大日期范围。 使用这两个日期,它就两个日期之间的范围内的值与Periods表联接。

    克里斯