2017-02-13 109 views
0

我正在尝试在MS ACCESS表上创建某种有效性(日期范围)字段。它将需要按ID,主题和级别分组来得出每条记录的有效期。如果没有采取相应的测试来提高成绩,则截至目前的有效期限将设置为99年12月31日。MS Access 2016中的SQL Server LEAD等效函数

我现在有如下表:

ID | Subject | Level | FromGrade | ToGrade | TestDate 
101 | Math | 5 | C+  | D  | 31/11/2016 
101 | Math | 4 | D   | A  | 01/12/2016 
101 | Math | 5 | D   | B+  | 12/12/2016 
101 | Math | 5 | B+  | A  | 25/12/2016 
102 | English | 4 | B   | B  | 20/12/2016 
102 | English | 4 | B   | C  | 28/12/2016 

结果表我应该得到以下的结尾:

ID | Subject | Level | FromGrade | ToGrade | TestDate | EffectiveTo 
101 | Math | 5 | C+  | D  | 31/11/2016 | 11/12/2016 
101 | Math | 4 | D   | A  | 01/12/2016 | 31/12/9999 
101 | Math | 5 | D   | B+  | 12/12/2016 | 24/12/2016 
101 | Math | 5 | B+  | A  | 25/12/2016 | 31/12/9999 
102 | English | 4 | B   | B  | 20/12/2016 | 27/12/2016 
102 | English | 4 | B   | C  | 28/12/2016 | 31/12/9999 

在SQL Server中做到这一点,我可以很容易地使用LEAD OVER功能:

SELECT [ID] 
, [Subject] 
, [Level] 
, [FromGrade] 
, [ToGrade] 
, [TestDate] 
, [EffectiveTo] = LEAD([TestDate], 1) OVER (PARTITION BY [ID], [Subject], [Level] ORDER BY [TestDate]) 
into StudentTable2 
FROM [dbo].[StudentTable1] 
ORDER BY [ID], [Subject], [Level], [TestDate] 

然后跟着一个

update [dbo].StudentTable2set [EffectiveTo] = DATEADD("DAY", -1, [EffectiveTo]) where EffectiveTo is not null 

但是,这是不是在MS Access/VBA脚本工作,有没有其他方式可以实现相同的结果?

+0

为什么不使用MS Access pass-thru查询保留准确的SQL Server查询?此外,这里没有VBA。 – Parfait

回答

1

您可以使用相关的子查询。要获取MS Access中的下一个值:

SELECT st.*, 
     (SELECT MIN(st2.TestDate) 
     FROM dbo.StudentTable1 as st2 
     WHERE st2.ID = st.ID AND 
       st2.Subject = st.Subject AND 
       st2.[Level] = st.[Level] AND 
       st2.TestDate > st.TestDate 
     ) as EffectiveTo 
FROM dbo.StudentTable1 as st 
ORDER BY [ID], [Subject], [Level], [TestDate]; 
+0

这将返回一个错误“您已经编写了一个子查询,它可以在不使用主查询的FROM子句中的EXISTS保留字的情况下返回多个字段,修改子查询的SELECT语句以仅请求一个字段” – user1688194

+0

@ user1688194。 。 。糟糕,应该是'MIN(TestDate)'。 –

+0

现在查询返回错误代码“您的查询不包含指定表达式'TestDate'作为聚合函数的一部分 – user1688194