【问题标题】:Showing week dates ranges as a part of select in SQL将星期日期范围显示为 SQL 中选择的一部分
【发布时间】:2018-01-31 13:31:01
【问题描述】:

我有一个查询每天获取计数,其中 startdate 和 enddate 是从应用程序传递的参数,我在这里使用示例日期来演示查询

SELECT  
    CAST(DateCreated AS DATE) AS Date, 
    COUNT(0) AS Total  
FROM 
    SessionTable
WHERE  
    DateCreated >= '10/02/2015'  
    AND CONVERT(DATE, DateCreated) <= '10/30/2015' 
GROUP BY
    CAST(DateCreated AS DATE) 
ORDER BY
    CAST(DateCreated AS DATE) 

这将以格式返回结果

Date Total 

现在我决定通过将按日期计数转换为按周计数来减少记录数,并使用查询

SELECT 
    DATEPART(wk, DateCreated) AS WeekNumber, 
    COUNT(0) AS WeekCount 
FROM 
    SessionTable
WHERE  
    DateCreated >= '10/02/2015'  
    AND CONVERT(DATE, DateCreated) <= '10/30/2015' 
GROUP BY 
    DATEPART(wk, DateCreated)

这会以格式返回结果并且工作正常

WeekNumber  WeekCount
-------------------------
  40           2298
  41          13998
  42          19454
  43          19923

为了使结果集更加清晰,我计划将每周的开始日期和结束日期也添加到上述结果集中,但很难这样做

我的预期结果是

    WeekNumber BeginDate  EndDate WeekCount 

要从这里获取 weekBegin 和 End Date How do you get the "week start date" and "week end date" from week number in SQL Server? 建议可以使用,我编写了这样的查询

         SELECT 
    DATEPART(wk, DateCreated) AS WeekNumber, 
    DATEADD(dd, -(DATEPART(dw, DateCreated)-1), DateCreated) as [WeekStart],
    DATEADD(dd, 7-(DATEPART(dw, DateCreated)), DateCreated)  as [WeekEnd],
    COUNT(0) AS WeekCount 
    FROM 
    Session
    WHERE  
    DateCreated >= '10/02/2015'  
    AND CONVERT(DATE, DateCreated) <= '10/30/2015' 
    GROUP BY 
    DATEPART(wk, DateCreated),
    DATEADD(dd, -(DATEPART(dw, DateCreated)-1), DateCreated),
    DATEADD(dd, 7-(DATEPART(dw, DateCreated)), DateCreated)

但这返回了我的结果集,每天计数为 1,如下所示

    WeekNumber  WeekStart       WeekEnd                     WeekCount
    44  2015-10-25 18:02:26.527 2015-10-31 18:02:26.527 1
    44  2015-10-25 10:53:16.057 2015-10-31 10:53:16.057 1
    42  2015-10-11 11:23:57.253 2015-10-17 11:23:57.253 1
    40  2015-09-27 09:04:39.063 2015-10-03 09:04:39.063 1
    44  2015-10-25 10:44:38.573 2015-10-31 10:44:38.573 1
    44  2015-10-25 14:33:31.803 2015-10-31 14:33:31.803 1
    44  2015-10-25 08:18:28.020 2015-10-31 08:18:28.020 1
    44  2015-10-25 12:19:21.270 2015-10-31 12:19:21.270 1

那么我怎样才能正确地将BeginDateEndDate 值添加到查询中的每一行?

【问题讨论】:

标签: sql sql-server


【解决方案1】:

我不知道如何在sql中实现。但是你可以试试这个:

Enumerable.Range(0, 7)
    .Select(i => "DateTime")
    .ToArray()

【讨论】:

    【解决方案2】:

    试试下面的代码:

    SELECT 
    DATEPART(wk, DateCreated) AS WeekNumber, 
    DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + year(datecreated)) + (DATEPART(wk, DateCreated)-1), 6) AS StartOfWeek,
    DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + year(datecreated)) + (DATEPART(wk, DateCreated)-1), 5) AS EndOfWeek
    COUNT(0) AS WeekCount 
    FROM 
    SessionTable
    WHERE  
    DateCreated >= '10/02/2015'  
    AND CONVERT(DATE, DateCreated) <= '10/30/2015' 
    GROUP BY 
    DATEPART(wk, DateCreated)
    

    更正

    您应该将 startofweek 和 endofweek 转换为日期数据类型,然后在 group by 子句中添加相同的数据类型。同样如下:

    SELECT 
    DATEPART(wk, DateCreated) AS WeekNumber, 
    CAST(DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + year(datecreated)) + (DATEPART(wk, DateCreated)-1), 6) AS DATE) AS StartOfWeek,
    CAST(DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + year(datecreated)) + (DATEPART(wk, DateCreated)-1), 5) AS DATE)  AS EndOfWeek
    COUNT(0) AS WeekCount 
    FROM SessionTable
    WHERE DateCreated >= '10/02/2015' AND CONVERT(DATE, DateCreated) <= '10/30/2015' 
    GROUP BY DATEPART(wk, DateCreated),
    CAST(DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + year(datecreated)) + (DATEPART(wk, DateCreated)-1), 6) AS DATE),
    CAST(DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + year(datecreated)) + (DATEPART(wk, DateCreated)-1), 5) AS DATE) 
    

    更新 2:

    SELECT 
    DATEPART(wk, DateCreated) AS WeekNumber, 
    CAST(DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + cast(year(datecreated) as varchar)) + (DATEPART(wk, DateCreated)-1), 6) AS DATE) AS StartOfWeek,
    CAST(DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + cast(year(datecreated) as varchar)) + (DATEPART(wk, DateCreated)-1), 5) AS DATE)  AS EndOfWeek
    COUNT(0) AS WeekCount 
    FROM SessionTable
    WHERE DateCreated >= '10/02/2015' AND CONVERT(DATE, DateCreated) <= '10/30/2015' 
    GROUP BY DATEPART(wk, DateCreated),
    CAST(DATEADD(wk, DATEDIFF(wk, 6, '1/1/' + cast(year(datecreated) as varchar)) + (DATEPART(wk, DateCreated)-1), 6) AS DATE),
    CAST(DATEADD(wk, DATEDIFF(wk, 5, '1/1/' + cast(year(datecreated) as varchar)) + (DATEPART(wk, DateCreated)-1), 5) AS DATE) 
    

    现在应该可以了。

    【讨论】:

    • 将收到一个语法错误,提示列 '.DateCreated' 在选择列表中无效,因为它不包含在聚合函数或 GROUP BY 子句中。
    • 现在的问题是将 varchar 值 '1/1/' 转换为数据类型 int 时转换失败。顺便说一句,根据我对问题的编辑提出任何建议
    • 经过我自己的一些研究并基于此线程中答案和 cmets 的建议,现在我得到了周开始日期和结束日期。但我可以看到 3 种不同的方法 [pastebin.com/pviVj3UM]。任何人都可以解释在所有情况下哪种方式最有效,例如年初的日期等
    【解决方案3】:

    如果您像这样修改您的查询,您应该会得到想要的结果。 问题是您按 DateCreated 分组,包括时间。 Cast to Date 解决了这个问题。

        SELECT 
        DATEPART(wk, DateCreated) AS WeekNumber, 
        DATEADD(dd, -(DATEPART(dw, CAST(DateCreated AS Date))-1), CAST(DateCreated AS Date)) as [WeekStart],
        DATEADD(dd, 7-(DATEPART(dw, CAST(DateCreated AS Date))), CAST(DateCreated AS Date))  as [WeekEnd],
        COUNT(0) AS WeekCount 
        FROM 
        Session
        WHERE  
        DateCreated >= '10/02/2015'  
        AND CONVERT(DATE, DateCreated) <= '10/30/2015' 
        GROUP BY 
        DATEPART(wk, DateCreated),
        DATEADD(dd, -(DATEPART(dw, CAST(DateCreated AS Date))-1), CAST(DateCreated AS Date)),
        DATEADD(dd, 7-(DATEPART(dw, CAST(DateCreated AS Date))), CAST(DateCreated AS Date))
    

    【讨论】:

    • 经过我自己的一些研究并基于此线程中答案和 cmets 的建议,现在我得到了周开始日期和结束日期。但我可以看到 3 种不同的方法 [pastebin.com/pviVj3UM]。任何人都可以解释在所有情况下哪种方式最有效,例如年初的日期等
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-22
    • 2015-05-07
    • 1970-01-01
    相关资源
    最近更新 更多