描述我的问题并不容易。 Task
在不同的时间范围内有不同的子任务。基于每个任务记录的(Task
表)日期,从子任务表中获取先前的子任务列表。
Task
表格包含T1Date
,T1Task
Subtask
表格包含T2Task
,T2SubTask
,T2Date
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日之后和
我需要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
答案 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