我创建了一个SQL用户定义函数来确定给定日期是否是日本假日。它现在由一系列函数组成,这些函数为* n *时间调用相同的内联视图,并且看起来不太明智。虽然我知道最好的现实解决方案是建立一个日历表,但我不敢废弃我写的所有代码行。我期待重构想法。感谢。
函数isholiday(d)只包含三个函数;每个都定义了三种日本假期。
DELIMITER //
CREATE FUNCTION isholiday(d date) RETURNS int
BEGIN
DECLARE t int;
CASE WHEN isregularholiday(d) = 1
THEN SET t = 1;
WHEN iscarryoverholiday(d) = 1
THEN SET t = 1;
WHEN isdentholiday(d) = 1
THEN SET t = 1;
ELSE SET t = 0; END CASE;
RETURN t;
END
//
isregularholiday(d)看起来像这样:
DELIMITER //
CREATE FUNCTION isregularholiday(d date) RETURNS int
BEGIN
DECLARE s int;
DECLARE t int;
SELECT count(*) INTO s
FROM (SELECT holiday_desc
, CASE WHEN SUBSTR(holiday_date, 3, 1) = '-'
THEN CAST(CONCAT_WS('-', YEAR(d), holiday_date) AS DATE)
WHEN holiday_date = 'ATH21'
THEN ATHLETIC_DATE(d)
/*There are six mobile holidays but I shall spare you the other five. */
ELSE NULL END cnvt
FROM holidays
WHERE YEAR(d) BETWEEN valid_from AND valid_to) **base**
WHERE cnvt = d;
CASE s WHEN 1 THEN SET t = 1;
ELSE SET t = 0;
END CASE;
RETURN t;
END
//
函数参数d(或其月 - 日期值)与holiday_date列没有直接匹配(参见cnvt = d),因为某些假期的确切日期在功能上取决于年份,因此CASE表达式分支为几个功能。该功能将始终引用内联视图 base 。
现在,除了基本假期外,还有两种类型的假期,它们都是善变的。我暂时称他们为结转假期和假期。结转假期的定义如下: 如果假日H在星期日,则第一个非假日工作日是H的结转假期。由于有几个假期被夹在一起,H的第一个非假日工作日不一定是第二天或星期一。
假期是两个假期之间的工作日。结转优先于假期。
由于移动假期,两种类型的假期都是移动和变化无常,并且必须计算一年。 iscarryoverholiday(d)查询 base 并计算d与d之前的星期日之间范围的行数。如果计数等于d与上一个星期日之间的日期差异,则d为结转假期。
isdentholiday(d)为d,d-1和d + 1调用isregularholiday()(每个参数的预期值为0,1,1)。它还为d(调用0)调用iscarryoverholiday(),因此它读取 base 四次。啊....
我不会再打扰你了。我只是想知道我是否可以做一些聪明的事情并定义一个最接近MySQL动态视图的东西。
感谢您阅读此内容!
以防万一,这里使用的假期不包括星期日。
答案 0 :(得分:1)
日历表根本没有任何逻辑。你填充一次,就是这样。
即使您计算并存储了世纪的每一天的假期状态(包括非假期的天数),您仍然会使用少于0.5 MB的磁盘空间。
date DATE,
isHoliday TINYINT,
isRegularHoliday TINYINT,
isCarryOverHoliday TINYINT,
isDentHoliday TINYINT
添加适当的索引后,您仍然只使用几个兆字节。
PK (date)
IX_HOLIDAY (isHoliday, date)
IX_RegularHoliday (isRegularHoliday, date)
IX_CarryOverHoliday (isCarryOverHoliday, date)
IX_DentHoliday (isDentHoliday, date)
然后,您可以简单地加入此表,以确定日期是否是特定类型的假期。如果需要,您甚至可以在is????Holiday()
函数中使用该表。
这是计算常数与存储常数的主要示例。你似乎能够做到后者,所以也许你应该...
答案 1 :(得分:0)
我写了一个名为Holiday List的脚本。基本上,它是一个表UDF作为参数传递一年,它返回一个“假期表”,然后我可以加入反对来查找假期。这可以为您提供一个起点和一些关于如何处理假期的想法,并且您可以将日本假期的规则添加到脚本...
http://www.sqlservercentral.com/scripts/Date+Manipulation/74302/
如果你想要脚本并且无法通过上述链接获取它,请告诉我,我会通过电子邮件发送给你...脚本是为 Microsoft SQL 编写的,它可能需要一些代码更改才能在 mySQL 下工作,但脚本中没有任何太多花哨的东西