-3

有没有办法在 SQL Server 中按月份对日期进行分组?

例如

Week 2: 05/07/2012 - 05/13/2012
Week 3: 05/14/2012 - 05/20/2012

但使用 Sql server 语句

我试过了

SELECT SOMETHING, 
     datediff(wk, convert(varchar(6), getdate(), 112) + '01', getdate()) + 1 AS TIME_
FROM STATISTICS_
GROUP BY something, TIME_
ORDER BY TIME_

但它返回月份的周数。(表示 3)

如何获得本周的天数?

例如,现在我们在第三 (3rd) 周,我想展示 05/14/2012 - 05/20/2012

以某种方式解决了:

SELECT DATEADD(ww, DATEDIFF(ww,0,<my_column_name>), 0)

select DATEADD(ww, DATEDIFF(ww,0,<my_column_name>), 0)+6

然后我会得到两天,稍后我会连接它们。

4

4 回答 4

3

好吧,在这里忍受我。我们将构建一个代表本月的临时日历表,包括该月之前和之后属于您定义的一周(星期一 - 星期日)的天数。我做了很多步骤来尝试使过程清晰,但在这种情况下我可能并不擅长这一点。

然后,我们可以生成不同周的范围,您可以使用它加入您的其他表格。

SET DATEFIRST 7;
SET NOCOUNT ON;

DECLARE @today SMALLDATETIME, @fd SMALLDATETIME, @rc INT;

SELECT @today = DATEADD(DAY, DATEDIFF(DAY, 0, GETDATE()), 0), -- today
    @fd = DATEADD(DAY, 1-DAY(@today), @today), -- first day of this month
    @rc = DATEPART(DAY, DATEADD(DAY, -1, DATEADD(MONTH, 1, @fd)));-- days in month

DECLARE @thismonth TABLE (
    [date]       SMALLDATETIME,
    [weekday]    TINYINT,
    [weeknumber] TINYINT 
);

;WITH n(d) AS (
    SELECT TOP (@rc+12) DATEADD(DAY, ROW_NUMBER() OVER 
    (ORDER BY [object_id]) - 7, @fd) FROM sys.all_objects
)
INSERT @thismonth([date], [weekday]) SELECT d, DATEPART(WEEKDAY, d) FROM n;

DELETE @thismonth WHERE [date] < (SELECT MIN([date]) FROM @thismonth WHERE [weekday] = 2)
                     OR [date] > (SELECT MAX([date]) FROM @thismonth WHERE [weekday] = 1);

;WITH x AS ( SELECT [date], weeknumber, rn = ((ROW_NUMBER() OVER 
   (ORDER BY [date])-1) / 7) + 1 FROM @thismonth ) UPDATE x SET weeknumber = rn;

- 现在,给出所有这些的最终查询(我只是将其分解以摆脱垂直滚动条):

;WITH ranges(w,s,e) AS (
    SELECT weeknumber, MIN([date]), MAX([date]) FROM @thismonth GROUP BY weeknumber
)
SELECT [week] = CONVERT(CHAR(10), r.s, 120) + ' - ' + CONVERT(CHAR(10), r.e, 120)

 --, SOMETHING , other columns from STATISTICS_?

 FROM ranges AS r

 -- LEFT OUTER JOIN dbo.STATISTICS_ AS s
 -- ON s.TIME_ >= r.s AND s.TIME_ < DATEADD(DAY, 1, r.e) 

 -- comment this out if you want all the weeks from this month: 
 WHERE w = (SELECT weeknumber FROM @thismonth WHERE [date] = @today)

 GROUP BY r.s, r.e --, SOMETHING
 ORDER BY [week];

带有 WHERE 子句的结果:

week
-----------------------
2012-05-14 - 2012-05-20

没有 WHERE 子句的结果:

week
-----------------------
2012-04-30 - 2012-05-06
2012-05-07 - 2012-05-13
2012-05-14 - 2012-05-20
2012-05-21 - 2012-05-27
2012-05-28 - 2012-06-03

请注意,我故意选择了 YYYY-MM-DD。您应该避免像 M/D/Y 这样的区域格式,尤其是对于输入和显示。无论您认为您的受众有多么有针对性,总会有人认为 2012 年 5 月 7 日是 7 月 5 日,而不是 5 月 7 日。使用 YYYY-MM-DD 没有任何歧义。

于 2012-05-18T13:31:25.533 回答
2

创建一个日历表,然后您可以查询周数、特定周和月的第一天/最后一天等。您还可以加入它查询以获取日期范围等。

于 2012-05-18T12:40:35.640 回答
0

案例陈述如何?

case when datepart(day, mydatetime) between 1 and 7 then 1
     when datepart(day, mydatetime) between 8 and 14 then 2
     ...

除非您希望所有第 1 周都在同一组中,否则您还必须包括年份和月份。

于 2012-05-18T12:38:41.177 回答
0

不清楚您是否要“按周对日期进行分组”,或者“从给定的一周中选择数据”

如果你的意思是“组”,这个小片段应该让你得到“每月的一周”:

SELECT   <stuff>
FROM     CP_STATISTICS
WHERE    Month(<YOUR DATE COL>) = 5 --april
GROUP BY  Year(<YOUR DATE COL>), 
          Month(<YOUR DATE COL>),
          DATEDIFF(week, DATEADD(MONTH, DATEDIFF(MONTH, 0, <YOUR DATE COL>), 0)
           , <YOUR DATE COL>) +1

或者,如果您想要“4 月第 1 周的销售,按日期排序”,您可以执行类似的操作。

DECLARE @targetDate datetime2 = '5/3/2012'
DECLARE @targetWeek int = DATEDIFF(week, DATEADD(MONTH, 
                             DATEDIFF(MONTH, 0, @targetDate), 0), @targetDate) +1


SELECT   <stuff>
FROM     CP_STATISTICS
WHERE    MONTH(@targetDate) = Month(myDateCol) AND
         YEAR(@targetDate)  = Year (myDateCol) AND 
         @targetWeek = DATEDIFF(week, DATEADD(MONTH, 
                                DATEDIFF(MONTH, 0, myDateCol), 0), myDateCol) +1
ORDER BY myDateCol

请注意,如果您使用非标准周数,或者想要跨月边界的周数进入前一个月的几天,事情会变得更加复杂。

编辑 2

通过查看您的“现在已解决”部分。我认为您的问题是“如何从给定一周的表格中获取数据?”

您的解决方案似乎是:

DECLARE @targetDate datetime2 = '5/1/2012'
DECLARE @startDate  datetime2 = DATEADD(ww, DATEDIFF(ww,0,targetDate), 0)
DECLARE @endDate    datetime2 = DATEADD(ww, DATEDIFF(ww,0,@now), 0)+6

SELECT  <stuff>
FROM    STATISTICS_
WHERE   dateStamp >= @startDate AND dateStamp <= @endDate

请注意,如果日期是 5 月 1 日,则此解决方案会导致开始日期为“2012 年 4 月 30 日”。我指出这一点是因为您的解决方案跨越了月份的界限。这可能是可取的,也可能不是可取的。

于 2012-05-18T12:40:40.323 回答