【问题标题】:Calendar table - Retrieve previous business dates日历表 - 检索以前的业务日期
【发布时间】:2016-04-15 21:22:04
【问题描述】:

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

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

如果当年当月的营业日比上年当月多,我需要检索上年当月的最大营业日。

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

提前感谢您的帮助。

【问题讨论】:

  • 这是一个很好的起点。 spaghettidba.com/2015/04/24/…
  • 感谢您的提示,我想知道人们如何如此轻松地创建格式化表格 :)
  • “准备”是什么意思?您只需要对日期进行选择声明吗?你可以只使用处理每一天的 UDF 吗?
  • 是的,我的意思是一个 select 语句,它将按原样检索日历表,并添加 DAY_MINUS1、MONTH_MINUS1 和 YEAR_MINUS1 列。不使用UDF会更容易,而只使用Select语句

标签: sql-server date calendar


【解决方案1】:

经过思考,这是我的解决方案:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-29
    相关资源
    最近更新 更多