我有一个表(它实际上是一个视图,但希望它的工作方式相同),其中包含保存所有日历日期的数据,以及一个标记,表示该日是否是我们执行预定付款运行的日期。此数据集是基于某些规则生成的,但不在手头的问题范围内。规则是我们每周运行一次付款(但这可以改为2周等),下面显示的结果集表示我们在每个星期五(7天)付款。列是实际日期,标志显示是否为付款日,标志显示是否为某种形式的假日日期。
CREATE TABLE Schedule
(
DateValue DATE NOT NULL,
IsPaymentDay BIT NOT NULL,
IsHoliday BIT NOT NULL
)
INSERT INTO Schedule
VALUES ('2013-01-01', 0, 1)
INSERT INTO Schedule
VALUES ('2013-01-02', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-03', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-04', 1, 0)
INSERT INTO Schedule
VALUES ('2013-01-05', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-06', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-07', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-08', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-09', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-10', 0, 1)
INSERT INTO Schedule
VALUES ('2013-01-11', 1, 1)
INSERT INTO Schedule
VALUES ('2013-01-12', 0, 1)
INSERT INTO Schedule
VALUES ('2013-01-13', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-14', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-15', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-16', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-17', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-17', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-18', 1, 0)
INSERT INTO Schedule
VALUES ('2013-01-19', 0, 0)
INSERT INTO Schedule
VALUES ('2013-01-20', 0, 0)
SELECT * FROM Schedule
DROP TABLE Schedule
您可以运行此代码来创建数据。
现在,我需要涵盖最后的业务规则。也就是说,如果付款运行属于公共假日,或办公室没有人员配备的那天(例如圣诞节期间),系统必须在地点关闭前一天进行付款运行,或者假期前一天。
所以,在下面的例子中,今年的第一次付款运行是1月4日星期五。那个是好的。它将按计划进行。
然而,下一次付款将于1月11日结束......但这是一个“公共假期”,办公室已关闭。事实上,它从10日开始关闭,并且只在13日重新开放。因此,在此示例中,我们需要在9日处理付款运行。
我需要具备一些功能。其中一个回答了问题,“今天是付款运行日吗?”。轻松完成:
SELECT *
FROM Schedule WHERE DateValue = CAST(GETDATE() AS DATE)
AND IsPaymentDay = 1
如果这是付款日,则返回一行。
但是,我需要考虑到办公室可能会关闭的事实。所以,我需要说:
SELECT *
FROM Schedule WHERE DateValue = CAST(GETDATE() AS DATE)
AND IsPaymentDay = 1
AND IsHoliday = 0
如果支付日这一天会好的话。但是,现在我被卡住了。如果我在办公室开放的最后一天运行这个,并且在今天收到的“关闭”期间有付款,那么它应该返回问题的真实结果。
所以,当我第9次运行它时,它应该表明第9个是付款日,因为有一个假期可以停止付款日。
我有一些想法,但不确定我能让他们工作,是:
调用检查日期是否为付款日期的函数...根据结果处理付款...然后调用获取下一个付款日期的函数。如果该日期属于假日,请选择当时和现在之间的所有日期,并将光标返回到它们,直到找到第一个可用的付款日期。如果那个日期是今天,那么这个过程。
但是,它看起来很混乱。希望有人可以帮我巧妙地做到这一点。
答案 0 :(得分:1)
尝试此查询
SELECT *
FROM Schedule
WHERE (DateDiff(dd,GETDATE(),DateValue) = 0 AND IsPaymentDay = 1 AND IsHoliday = 0)
OR ( DateDiff(dd,GETDATE(),DateValue) = 0 AND IsPaymentDay = 0 AND IsHoliday = 0 AND
EXISTS(
SELECT *
FROM Schedule holiday
WHERE DateDiff(dd,GETDATE(),DateValue) BETWEEN 1 AND 6 AND IsPaymentDay = 1 AND IsHoliday = 1
AND NOT EXISTS (SELECT *
FROM Schedule
WHERE DateDiff(dd,GETDATE(),Schedule.DateValue) >= 1 AND DateDiff(dd,Schedule.DateValue,holiday.DateValue)>=1
AND Schedule.IsHoliday = 0 AND Schedule.IsPaymentDay=0)
)
)
我在这里检查接下来的7天(BETWEEN 1 AND 6
)。您可以根据您的要求柚木。如果您需要检查今天的所有记录,只需将其更改为>=1
即可。像这样:
SELECT *
FROM Schedule
WHERE (DateDiff(dd,GETDATE(),DateValue) = 0 AND IsPaymentDay = 1 AND IsHoliday = 0)
OR ( DateDiff(dd,GETDATE(),DateValue) = 0 AND IsPaymentDay = 0 AND IsHoliday = 0 AND
EXISTS(
SELECT *
FROM Schedule holiday
WHERE DateDiff(dd,GETDATE(),DateValue) >=1 AND IsPaymentDay = 1 AND IsHoliday = 1
AND NOT EXISTS (SELECT *
FROM Schedule
WHERE DateDiff(dd,GETDATE(),Schedule.DateValue) >= 1 AND DateDiff(dd,Schedule.DateValue,holiday.DateValue)>=1
AND Schedule.IsHoliday = 0 AND Schedule.IsPaymentDay=0)
)
)
答案 1 :(得分:1)
你甚至可以在SQL语句中实现这一点 -
SELECT *
FROM Schedule S1
WHERE Datevalue = CAST(Getdate() AS DATE)
AND Datevalue =
(SELECT MAX(Datevalue)
FROM Schedule S2
WHERE Datevalue <= (SELECT MIN(Datevalue)
FROM Schedule S3
WHERE Datevalue >= S1.Datevalue
AND Ispaymentday = 1)
AND Isholiday = 0);
修改强>
要查看所有付款日,您可以删除gatdate
值 -
SELECT *
FROM Schedule S1
WHERE Datevalue =
(SELECT MAX(Datevalue)
FROM Schedule S2
WHERE Datevalue <= (SELECT MIN(Datevalue)
FROM Schedule S3
WHERE Datevalue >= S1.Datevalue
AND Ispaymentday = 1)
AND Isholiday = 0);
答案 2 :(得分:0)
尝试此功能:
create Function IsPaymentDate (@date Date) returns int
as
begin
declare @IsPaymentDate int
select @IsPaymentDate =
case DateDiff(dd, max(a.Datevalue), @date)
when 0 then 1
else 0
end
from Schedule a
where a.Isholiday = 0 and
a.Datevalue <= (select min(b.Datevalue) from Schedule b
where b.Datevalue >= @date and b.Ispaymentday = 1)
return @IsPaymentDate
end