从日期时间列获取一个月内的周数

时间:2011-09-19 18:52:23

标签: sql sql-server sql-server-2005 tsql sql-server-2008

我有一个名为FcData的表,数据如下:

Op_Date

2011-02-14 11:53:40.000
2011-02-17 16:02:19.000
2010-02-14 12:53:40.000
2010-02-17 14:02:19.000

我希望从Op_Date获得该月的周数。所以我正在寻找输出:

 Op_Date                       Number of Weeks

    2011-02-14 11:53:40.000       5   
    2011-02-17 16:02:19.000       5
    2010-02-14 12:53:40.000       5
    2010-02-17 14:02:19.000       5

7 个答案:

答案 0 :(得分:2)

此页面有一些很好的功能可以找出任何给定月份的最后一天:http://www.sql-server-helper.com/functions/get-last-day-of-month.aspx

使用DATEPART(wk, last_day_of_month)调用包装该函数的输出。将它与每周第一天的同等通话相结合,可以获得该月的周数。

答案 1 :(得分:1)

使用此选项可获取特定日期的周数。将GetDate()替换为您的日期:

declare @dt date = cast(GetDate() as date);
declare @dtstart date =  DATEADD(day, -DATEPART(day, @dt) + 1, @dt);
declare @dtend date = dateadd(DAY, -1, DATEADD(MONTH, 1, @dtstart));

WITH dates AS (
     SELECT @dtstart ADate
     UNION ALL
     SELECT DATEADD(day, 1, t.ADate) 
       FROM dates t
      WHERE DATEADD(day, 1, t.ADate) <= @dtend
)
SELECT top 1 DatePart(WEEKDAY, ADate) weekday, COUNT(*) weeks
  FROM dates d
  group by DatePart(WEEKDAY, ADate)
  order by 2 desc

解释:CTE创建一个结果集,其中包含给定日期月份的所有日期。然后我们查询结果集,按工作日分组并计算出现次数。最大数量将给出我们每个月重叠的周数(前提:如果月份有5个星期一,它将涵盖一年中的五周)。

<强>更新

现在,如果您有多个日期,则应相应调整,将您的查询与dates CTE结合使用。

答案 2 :(得分:1)

这是我的看法,可能错过了一些东西。

在Linq:

from u in TblUsers
let date = u.CreateDate.Value
let firstDay = new DateTime(date.Year, date.Month, 1)
let lastDay = firstDay.AddMonths(1)
where u.CreateDate.HasValue
select Math.Ceiling((lastDay - firstDay).TotalDays / 7)

并生成SQL:

-- Region Parameters
DECLARE @p0 Int = 1
DECLARE @p1 Int = 1
DECLARE @p2 Float = 7
-- EndRegion
SELECT CEILING(((CONVERT(Float,CONVERT(BigInt,(((CONVERT(BigInt,DATEDIFF(DAY, [t3].[value], [t3].[value2]))) * 86400000) + DATEDIFF(MILLISECOND, DATEADD(DAY, DATEDIFF(DAY, [t3].[value], [t3].[value2]), [t3].[value]), [t3].[value2])) * 10000))) / 864000000000) / @p2) AS [value]
FROM (
    SELECT [t2].[createDate], [t2].[value], DATEADD(MONTH, @p1, [t2].[value]) AS [value2]
    FROM (
        SELECT [t1].[createDate], CONVERT(DATETIME, CONVERT(NCHAR(2), DATEPART(Month, [t1].[value])) + ('/' + (CONVERT(NCHAR(2), @p0) + ('/' + CONVERT(NCHAR(4), DATEPART(Year, [t1].[value]))))), 101) AS [value]
        FROM (
            SELECT [t0].[createDate], [t0].[createDate] AS [value]
            FROM [tblUser] AS [t0]
            ) AS [t1]
        ) AS [t2]
    ) AS [t3]
WHERE [t3].[createDate] IS NOT NULL

答案 3 :(得分:0)

根据这篇MSDN文章:http://msdn.microsoft.com/en-us/library/ms174420.aspx,您只能获得当年的当前周,而不是该月的回报。

答案 4 :(得分:0)

可能有各种方法来实现这个想法suggested by @Marc B。这是一个,没有使用UDF但直接计算月份的第一天和最后几天:

WITH SampleData AS (
  SELECT CAST('20110214' AS datetime) AS Op_Date
  UNION ALL SELECT '20110217'
  UNION ALL SELECT '20100214'
  UNION ALL SELECT '20100217'
  UNION ALL SELECT '20090214'
  UNION ALL SELECT '20090217'
),
MonthStarts AS (
  SELECT
    Op_Date,
    MonthStart = DATEADD(DAY, 1 - DAY(Op_Date), Op_Date)
    /* alternatively: DATEADD(MONTH, DATEDIFF(MONTH, 0, Op_Date), 0) */
  FROM FcData
),
Months AS (
  SELECT
    Op_Date,
    MonthStart,
    MonthEnd = DATEADD(DAY, -1, DATEADD(MONTH, 1, MonthStart))
  FROM FcData
)
Weeks AS (
  SELECT
    Op_Date,
    StartWeek = DATEPART(WEEK, MonthStart),
    EndWeek   = DATEPART(WEEK, MonthEnd)
  FROM MonthStarts
)
SELECT
  Op_Date,
  NumberOfWeeks = EndWeek - StartWeek + 1
FROM Weeks

所有计算都可以在一个SELECT中完成,但我选择将它们分成几个步骤并将每个步骤放在一个单独的CTE中,这样可以更好地看到最终结果是如何获得的。

答案 5 :(得分:0)

您可以使用以下方法获得每月的周数。

Datepart(WEEK,
         DATEADD(DAY,
                 -1,
                 DATEADD(MONTH,
                         1,
                         DATEADD(DAY,
                                 1 - DAY(GETDATE()),
                                 GETDATE())))
         -
         DATEADD(DAY,
                 1 - DAY(GETDATE()),
                 GETDATE())
         +1
         )

答案 6 :(得分:0)

在这里您可以获得准确的周数:

DECLARE @date DATETIME
SET @date = GETDATE()
SELECT ROUND(cast(datediff(day, dateadd(day, 1-day(@date), @date), dateadd(month, 1, dateadd(day, 1-day(@date), @date))) AS FLOAT) / 7, 2)

使用 2014年9月的代码,您将获得 4.29 ,这实际上是正确的,因为已经整整4周,还有2天。