日历表 - 检索以前的业务日期

时间:2016-01-11 14:18:10

标签: sql-server date calendar

我目前正在开展一个项目,我需要以某种方式准备日历表。 这是我的参考日历表:

+----------+----------+------+-------+-----+--------------+--+
| DATE_ID  | MONTH_ID | YEAR | MONTH | DAY | BUSINESS_DAY |  |
+----------+----------+------+-------+-----+--------------+--+
| 20160101 |   201601 | 2016 |     1 |   1 |            0 |  |
| 20160102 |   201601 | 2016 |     1 |   2 |            0 |  |
| 20160103 |   201601 | 2016 |     1 |   3 |            0 |  |
| 20160104 |   201601 | 2016 |     1 |   4 |            1 |  |
| 20160105 |   201601 | 2016 |     1 |   5 |            2 |  |
+----------+----------+------+-------+-----+--------------+--+

我需要根据工作日检索前一天,一个月和一年的DATE_ID字段。 例如,要检索前一天,我会加入:

YEAR = YEAR
MONTH = MONTH
BUSINESS_DAY = BUSINESS_DAY - 1
And an extra condition if BUSINESS_DAY = 1, previous BUSINESS_DAY = 1

要检索上个月,我会执行以下操作:

YEAR = YEAR
MONTH = MONTH - 1
BUSINESS_DAY = BUSINESS_DAY

但是当我们当月的营业日多于上个月时,我遇到了问题。在这种情况下,我需要检索上个月的最大工作日。 例如,假设3月31日是工作日22,2月只有21个工作日,3月30日(工作日20)和3月31日(工作日21)的上个月日期将是2月29日(工作日20,本月最大工作日)。

我有一个类似的问题要检索前一年,正如我所做的那样:

YEAR = YEAR - 1
MONTH = MONTH 
BUSINESS_DAY = BUSINESS_DAY

如果本月当前年度的营业日多于上一个当月,我需要检索上一个当月的最大营业日。

我怎么能以这种方式准备我的日历表?我无法修改日历表的结构,我只能在请求中“准备”我需要的日历表。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

在思考之后,这是我带来的解决方案:

Select RBC.*, RBC2.DATE_ID AS DATE_ID_DM1, RBC3.DATE_ID AS DATE_ID_MM1, RBC4.DATE_ID AS DATE_ID_YM1 FROM CALENDAR RBC
LEFT JOIN CALENDAR RBC2 ON RBC.BILL_YEAR = RBC2.BILL_YEAR AND RBC.BILL_MONTH = RBC2.BILL_MONTH AND ((RBC.BUS_DAY > 1 AND RBC.BUS_DAY - 1 = RBC2.BUS_DAY) OR (RBC.BUS_DAY = 1 AND RBC.BUS_DAY = RBC2.BUS_DAY))
LEFT JOIN (Select max(BUS_DAY) as MAX_BUS_DAY_M1, MONTH_ID FROM CALENDAR GROUP BY MONTH_ID) MAXRBC_M ON MAXRBC_M.MONTH_ID = RBC.MONTH_ID - 1 
LEFT JOIN (Select max(BUS_DAY) as MAX_BUS_DAY_Y1, MONTH_ID FROM CALENDAR GROUP BY MONTH_ID) MAXRBC_Y ON MAXRBC_Y.MONTH_ID = RBC.MONTH_ID - 100
LEFT JOIN CALENDAR RBC3 ON RBC.BILL_YEAR = RBC3.BILL_YEAR AND ((RBC.BILL_MONTH > 1 AND RBC.BILL_MONTH - 1 = RBC3.BILL_MONTH) OR (RBC.BILL_MONTH = 1 AND RBC.BILL_MONTH = RBC3.BILL_MONTH)) AND RBC.BUS_DAY != 0 AND ((RBC.BUS_DAY <= MAXRBC_M.MAX_BUS_DAY_M1 AND RBC.BUS_DAY = RBC3.BUS_DAY) OR (RBC.BUS_DAY > MAXRBC_M.MAX_BUS_DAY_M1 AND RBC3.BUS_DAY = MAXRBC_M.MAX_BUS_DAY_M1))
LEFT JOIN CALENDAR RBC4 ON RBC.BILL_YEAR - 1 = RBC4.BILL_YEAR AND RBC.BILL_MONTH = RBC4.BILL_MONTH AND RBC.BUS_DAY != 0 AND ((RBC.BUS_DAY <= MAXRBC_Y.MAX_BUS_DAY_Y1 AND RBC.BUS_DAY = RBC4.BUS_DAY) OR (RBC.BUS_DAY > MAXRBC_Y.MAX_BUS_DAY_Y1 AND RBC4.BUS_DAY = MAXRBC_Y.MAX_BUS_DAY_Y1))

我认为它不是最佳的,但似乎有效!