回过头来看一下数据表

时间:2013-06-09 06:20:03

标签: sql sql-server

我有一个表(它实际上是一个视图,但希望它的工作方式相同),其中包含保存所有日历日期的数据,以及一个标记,表示该日是否是我们执行预定付款运行的日期。此数据集是基于某些规则生成的,但不在手头的问题范围内。规则是我们每周运行一次付款(但这可以改为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个是付款日,因为有一个假期可以停止付款日。

我有一些想法,但不确定我能让他们工作,是:

调用检查日期是否为付款日期的函数...根据结果处理付款...然后调用获取下一个付款日期的函数。如果该日期属于假日,请选择当时和现在之间的所有日期,并将光标返回到它们,直到找到第一个可用的付款日期。如果那个日期是今天,那么这个过程。

但是,它看起来很混乱。希望有人可以帮我巧妙地做到这一点。

3 个答案:

答案 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