我目前正在开展一个项目,我需要以某种方式准备日历表。 这是我的参考日历表:
+----------+----------+------+-------+-----+--------------+--+
| 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
如果本月当前年度的营业日多于上一个当月,我需要检索上一个当月的最大营业日。
我怎么能以这种方式准备我的日历表?我无法修改日历表的结构,我只能在请求中“准备”我需要的日历表。
提前感谢您的帮助。
答案 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))
我认为它不是最佳的,但似乎有效!