每个记录的早期日期的SQL链接表

时间:2015-03-13 04:39:46

标签: sql

描述我的问题并不容易。 Task在不同的时间范围内有不同的子任务。基于每个任务记录的(Task表)日期,从子任务表中获取先前的子任务列表。

  • Task表格包含T1DateT1Task
  • Subtask表格包含T2TaskT2SubTaskT2Date

  • Table2.T2Task指向Table1.T1Task

  • 的链接

Table2列出每个任务的所有子任务和每个子任务的生效日期。

例如:

表1记录:

01/17/2015, Task1
02/24/2015, Task1
03/01/2015, Task2
05/01/2015, Task2

在不同的日期执行了四项任务。

表2记录:

Task1, SubTask1_1, 01/15/2015
Task1, SubTask1_2, 01/15/2015
Task1, SubTask1_3, 01/15/2015
Task1, SubTask1_1, 02/15/2015
Task1, SubTask1_4, 02/15/2015
Task2, SubTask2_1, 01/01/2015
Task2, SubTask2_2, 04/01/2015
Task2, SubTask2_3, 07/01/2015

这意味着Task1携带子任务1_1,1_2和1_3,如果它发生在2015年1月15日到2015年2月14日之间。并且Task1在2015年2月15日之后和

之后变为子任务1_1和1_4

我需要SQL结果:

01/17/2015, Task1, SubTask1_1, 01/15/2015
01/17/2015, Task1, SubTask1_2, 01/15/2015
01/17/2015, Task1, SubTask1_3, 01/15/2015
02/24/2015, Task1, SubTask1_1, 02/15/2015
02/24/2015, Task1, SubTask1_4, 02/15/2015
03/01/2015, Task2, SubTask2_1, 01/01/2015
05/01/2015, Task2, SubTask2_2, 04/01/2015

我可以使用下面的SQL来获取硬编码日期的最新结果。但是,我不知道如何使用覆盖记录的T1Date替换下面的SQL上的#2/1/2015#。

SELECT 
    T1Date, T1Task, T2SubTask, T2Date 
FROM 
    Table1 
INNER JOIN 
    (SELECT 
         Table2.T2Task, Table2.T2subTask, MAX(Table2.T2Date) as maxdate 
     FROM 
         Table2 
     WHERE 
         Table2.T2Date <= #2/1/2015# 
     GROUP by 
         T2subtask) AS b ON Table1.T1Task = b.T2Task AND Table2.Date = b.maxdate

2 个答案:

答案 0 :(得分:0)

如果您使用的是SQLServer 2012或更高版本,则可以使用OVER窗口函数的ROWS参数从Table1获取上一个日期,创建T2日期应包含的日期范围:

;WITH Table1WithPriorDate AS (
    SELECT  T1Task
    ,       T1Date
    ,       MIN(T1Date) OVER (
                PARTITION BY T1Task
                ORDER BY T1Date
                ROWS BETWEEN 1 PRECEDING AND CURRENT ROW
            ) AS PriorDate
    FROM    Table1
), T1Tasks AS (
    SELECT  T1Task
    ,       T1Date
    ,       CASE PriorDate
            WHEN T1Date THEN 'January 1, 1753'
            ELSE PriorDate
            END AS PriorDate
    FROM    Table1WithPriorDate
)
SELECT  T1Task
,       T1Date
,       PriorDate
,       ISNULL( T2Task, 'null' ) AS T2Task
,       ISNULL( T2SubTask, 'null' ) AS T2SubTask
,       ISNULL( T2Date, DATEADD(YEAR,100,GETDATE()) ) AS T2Date
FROM    T1Tasks AS T1
LEFT JOIN   Table2 AS T2
    ON  T2.T2Task = T1.T1Task
    AND T2.T2Date BETWEEN PriorDate AND T1Date

SQLFiddle链接:http://sqlfiddle.com/#!6/5a2b6/59

答案 1 :(得分:0)

如果您没有SQL Server 2012或更高版本,则可以在select中使用相关子查询来确定每个任务的先前日期

;WITH T1Tasks AS (
    SELECT t.*
    ,      ISNULL((SELECT MAX(p.T1Date) FROM Table1 AS p WHERE p.T1Task = t.T1Task AND p.T1Date < t.T1Date),'January 1, 1753') AS PriorDate
    FROM   Table1 AS t
)
SELECT  T1Task
,       T1Date
,       PriorDate
,       ISNULL( T2Task, 'null' ) AS T2Task
,       ISNULL( T2SubTask, 'null' ) AS T2SubTask
,       ISNULL( T2Date, DATEADD(YEAR,100,GETDATE()) ) AS T2Date
FROM    T1Tasks AS T1
LEFT JOIN   Table2 AS T2
    ON  T2.T2Task = T1.T1Task
    AND T2.T2Date BETWEEN PriorDate AND T1Date

SQLFiddle链接:http://sqlfiddle.com/#!6/5a2b6/66/0