2013-06-09 2 views
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 

Вы можете запустить этот код для создания данных.

Теперь мне нужно заполнить последнее бизнес-правило. То есть, если прогон платежей приходится на праздничный день или на день, когда офис не укомплектован (например, Рождественский период), система должна выполнить оплату за день до закрытия места или за день до праздника.

Итак, в приведенном ниже примере первый расчетный год - пятница 4-го января. Это один из вариантов. Он будет уходить, как и планировалось.

Следующий платеж, однако, уходит 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-й день является платежным днем, потому что есть праздничный период, который остановит день оплаты от увольнения.

Несколько идея у меня есть, но не уверен, что я могу заставить их работать, это:

вызова функция, которая проверяет, является ли дата является датой оплаты ... процесс выплаты, в зависимости от результата. затем вызовите функцию, которая получает следующую дату платежа. Если эта дата выпадает на праздничный день, выберите все даты между ними и сейчас, а затем верните курсор, пока я не найду первую доступную дату платежа. Если эта дата сегодня, этот процесс.

Но, кажется, грязный. Надеюсь, кто-то может помочь мне сделать это аккуратно.

ответ

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) 
      ) 
     ) 
+0

Спасибо! Набор результатов всегда пуст ... Не уверен, что я делаю неправильно. – Craig

+0

@Craig: вы заменили GetDate() на дату, которую нужно проверить? Я заменил его на 2013-01-04, 2013-01-09,2013-01-10,2013-01-11 в 4 разных тестах, и он вернул правильную строку. –

+0

Извините @Khanh! Я этого не сделал. Добавлена ​​переменная @DateToTest, заменила GetDates и привет прета! Вау! Благодаря! Кажется, это работает отлично. Я собираюсь проверить это сейчас ... но похоже, что это трюк! Благодарю. – Craig

1

вы можете даже achive это в 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); 

Редактировать

, чтобы увидеть все paymentday вы можете удалить 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); 
+0

Я не получаю никаких результатов назад. Поблагодарите. – Craig

+0

@Craig Может быть, потому что ваша системная дата не является платежным днем. –

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 
Смежные вопросы