【问题标题】:Get month name with different month start and end dates获取具有不同月份开始和结束日期的月份名称
【发布时间】:2014-03-17 09:30:37
【问题描述】:

显然,获取当前日期的月份很简单,但我需要获取具有不同结束日期的月份名称。

我需要获取月份名称,该月份的开始日期是该月第一个星期三之后的第一个星期四,该月的结束日期是下个月的第一个星期三。这是会计方面的事情,所以我不打算与规范争论!

例如对于 2014 年,1 月的运行时间为 1 月 9 日至 2 月 5 日,2 月的运行时间为 2 月 6 日至 3 月 5 日,3 月的运行时间为 3 月 6 日至 4 月 2 日。

【问题讨论】:

  • 那么,如果一个月从星期四开始,则上个月与本月重叠一周(因为第一个星期三是该月的 7 号,但第一个星期四是 1 号)?我怀疑情况是否如此,所以我怀疑规范需要调整(或者,如果不需要,那么在这些期间正确的答案是什么?)
  • @Damien_The_Unbeliever 在这种情况下,它将在周四的第 2 天开始 - 将更新最初的问题!

标签: sql sql-server-2008


【解决方案1】:

我建议您创建一个包含“会计月份”的表格,其中包含开始日期、结束日期和月份名称列。

然后您可以查询它以查找日期在开始日期和结束日期之间的行并返回月份名称。将其放入标量函数将使其可重复使用,并且在接下来的几个月中也相对容易更新。

【讨论】:

  • 虽然我同意这是最简单的,但不一定是最可持续的!
  • @franglais - 只需 1000 行,您就可以建模超过 80 年。填充这样的表应该不会花费很长时间。把它作为一个表达式/函数来做可能会很痛苦(并不是说我不想弄清楚一个:-))
  • @Damien_The_Unbeliever 足够公平 - 无需手动填充表格的最佳方式?
  • @franglais - 您可能需要告诉我们管理您的开始和结束月份的规则。
  • 抱歉,刚刚再看了一下这个问题,可以看到你已经有了...
【解决方案2】:

我认为,根据 Paddy 的 answer,查找表是最简单的事情。这是为其生成行的一种方法:

; With Numbers(n) as (
    select 4 union all select 5
), Months as (
    select CONVERT(date,'20010104') as StartDt,CONVERT(date,'20010207') as EndDt,
           DATENAME(month,'20010103') as Month
    union all
    select DATEADD(week,n1.n,StartDt),DATEADD(week,n2.n,EndDt),
           DATENAME(month,DATEADD(week,n1.n,StartDt))
    from Months,Numbers n1,Numbers n2 --Old-skool join, just for once
    where DATEPART(day,DATEADD(week,n1.n,StartDt)) between 2 and 8 and
          DATEPART(day,DATEADD(week,n2.n,EndDt)) between 1 and 7 and
          StartDt < '21000101'
)
select * from Months option (maxrecursion 0)

(CW 因为这实际上只是对 Paddy 答案的扩展,但我不想编辑他们的答案,也不适合发表评论

【讨论】:

  • 忽略该评论,我很厚:D
  • 只是对那个(出色的)查询的一个小建议。当前查询会将结束日期恢复为日期 00:00:00,而将其恢复为日期 23:59:59 会更好!
  • @franglais - 如果您这么想,那么您可能应该在第二天返回并使用&lt; 进行比较,而不是&lt;=BETWEEN。如果涉及时间,则使用开始值为包含而结束值为​​不包含的半开放区间几乎总是更干净。因为我确定您不想排除例如时间戳为 23:59:59.537 的值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多