1

我有一个表格(它实际上是一个视图,但希望它的工作原理相同),其中包含包含所有日历日期的数据,以及一个标志,表明那一天是否是我们进行预定付款运行的一天。该数据集是根据一些规则生成的,但超出了当前问题的范围。规则是我们每周运行一次付款(但这可以更改为每 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

这表示这一天是否可以作为付款日。但是,现在我被困住了。如果我在办公室开放的最后一天运行此程序,并且在今天进行的“关闭”期间有付款,那么它应该为该问题返回 TRUE 结果。

因此,当我在 9 日运行它时,它应该表明 9 日是付款日,因为有一个假期会阻止付款日的触发。

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

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

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

4

3 回答 3

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)
             )
        )
于 2013-06-09T07:06:52.437 回答
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);
于 2013-06-09T07:11:37.523 回答
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
于 2013-06-09T07:32:06.843 回答