标题的复杂' - 部分可能是主观的,但对我来说,它相当复杂。
我有一个名为Contracts (C)
和FinancialYears (FY)
的表格。如果满足特定状态,合同将具有多个财务年度(每年一个),自动创建(例如,取消的合同不会获得新的财务年度记录,但已批准的合同将会生效)。它是每年具有特定地位的FY。例如:
--------------------FinancialYears-------------------
ContractID: 1 | 1 | 1
StatusID: 2 | 3 | 5
dStart: 01-01-2012 | 01-01-2013 | 01-01-2014
dEnd: 31-12-2012 | 31-12-2013 | 31-12-2014
Year: 2012 | 2013 | 2014
-----------------------------------------------------
(For example: StatusID (2, 3, 5), (Proposed, Approved, Cancelled))
现在假设一个用户想知道在这个时间点批准了多少合同,那么查询应该查看合同的最近一个财政年度,这就是我的意思。很难过。
我必须编写一个执行以下操作的查询:
SELECT *
FROM Contracts C
INNER JOIN FinancialYears FY ON FY.ContractID = C.ContractID
WHERE StatusID = X AND (dStart < GETDATE() AND dEnd > GETDATE())
// This would search on the financial year of the contract which has its valid
period in-between today.
但是,例如,由于取消的合同将在明年没有新的财政年度,我今天永远无法查询已取消的2014年合同,所以我需要调整以下条件到查询以某种方式:
// IF (dStart < GETDATE() AND dEnd > GETDATE()) RETURNS 0, THEN DO INSTEAD:
SELECT TOP 1
//
WHERE (dEnd < GETDATE)
ORDER BY ENDDATE DESC
// With other words: if there is no ongoing financial year between the given time interval,
then select the most recent financial year in the past.
有人可以帮助我吗?
谢谢。
答案 0 :(得分:1)
如果我没有弄错的话,您只需要过滤当前日期在合同的开始日期和结束日期之间的合同。
MS SQL Server架构设置:
CREATE TABLE FinancialYearContracts
([ContractID] int, [StatusID] int, [dStart] datetime, [dEnd] datetime, [Year] int)
;
INSERT INTO FinancialYearContracts
([ContractID], [StatusID], [dStart], [dEnd], [Year])
VALUES
(1, 2, '2012-01-01 00:00:00', '2012-12-31 00:00:00', 2012),
(1, 3, '2013-01-01 00:00:00', '2013-12-31 00:00:00', 2013),
(1, 5, '2014-01-01 00:00:00', '2014-12-31 00:00:00', 2014),
(2, 2, '2013-01-01 00:00:00', '2013-12-31 00:00:00', 2013),
(2, 3, '2014-01-01 00:00:00', '2014-12-31 00:00:00', 2014),
(2, 3, '2015-01-01 00:00:00', '2015-12-31 00:00:00', 2015),
(3, 2, '2014-01-01 00:00:00', '2014-12-31 00:00:00', 2014),
(3, 3, '2015-01-01 00:00:00', '2015-12-31 00:00:00', 2015),
(4, 2, '2014-01-01 00:00:00', '2014-12-31 00:00:00', 2014),
(5, 2, '2013-01-01 00:00:00', '2013-12-31 00:00:00', 2013),
(5, 3, '2014-01-01 00:00:00', '2014-12-31 00:00:00', 2014),
(5, 3, '2015-01-01 00:00:00', '2015-12-31 00:00:00', 2015),
(6, 2, '2013-01-01 00:00:00', '2013-12-31 00:00:00', 2012),
(6, 3, '2014-01-01 00:00:00', '2014-12-31 00:00:00', 2013),
(6, 5, '2015-01-01 00:00:00', '2015-12-31 00:00:00', 2014)
;
查询以生成结果:
declare @DateFilter as datetime = GETDATE()
declare @Status as int = 3
SELECT *
FROM FinancialYearContracts
WHERE @DateFilter BETWEEN dStart AND dEnd AND StatusID = @Status
<强> Results 强>:
| CONTRACTID | STATUSID | DSTART | DEND | YEAR |
|------------|----------|--------------------------------|---------------------------------|------|
| 2 | 3 | January, 01 2015 00:00:00+0000 | December, 31 2015 00:00:00+0000 | 2015 |
| 3 | 3 | January, 01 2015 00:00:00+0000 | December, 31 2015 00:00:00+0000 | 2015 |
| 5 | 3 | January, 01 2015 00:00:00+0000 | December, 31 2015 00:00:00+0000 | 2015 |
这表示根据我放在一起的样本数据,目前处于批准状态的合同。
答案 1 :(得分:1)
这是一个快速模拟:
SELECT *
FROM Contracts C
cross apply (
select top 1 ContractID
from FinancialYears where dStart < GETDATE()
order by dEnd desc
) F on C.ConractID = F.ContractID
但是您可能需要一些额外的标准来查找所有合同,例如客户代码或其他内容。