【问题标题】:Select last 30 days with a sql query使用 sql 查询选择过去 30 天
【发布时间】:2011-08-24 07:54:20
【问题描述】:

我正在查找过去 30 天内的周一、周二、周三、周四、周五、周六、周日的数量。我可以在没有实际数据库表的情况下选择过去 30 天的日期和星期几吗?类似的东西

SELECT --everything between
convert(date,GETDATE()), DATENAME(DW, GETDATE())
--and
convert(date,GETDATE() - 30), DATENAME(DW, GETDATE())

【问题讨论】:

  • 嗯...什么?您是从临时表或变量表中选择还是什么?无论哪种方式,答案都是肯定的,但您的代码并不完全理想。
  • @Tejs - 我对我的问题进行了更改。我正在查找过去 30 天内一周中的每一天的次数。

标签: sql sql-server sql-server-2008


【解决方案1】:

您可以使用递归 CTE:

;WITH CTE AS
(
    SELECT convert(date,GETDATE()) sDate, DATENAME(DW, GETDATE()) sDayofWeek
    UNION ALL
    SELECT DATEADD(DAY,-1,sDate), DATENAME(DW, DATEADD(DAY,-1,sDate))
    FROM CTE
    WHERE sDate > GETDATE()-29
)
SELECT * FROM CTE

【讨论】:

  • @user54197 -- 你可能想看看我的答案 -- 更快。
  • @Hogan - 没错,但我的回答是针对最初的问题,而不是现在的问题。无论如何,您对新问题的回答是正确的,并且操作应该与它一起使用
  • 感谢您的评论。我想知道 OP 到底想要什么。
【解决方案2】:
WITH cteCount AS (
    SELECT DATENAME(dw, GETDATE()) dw, 1 ix 
    UNION ALL 
    SELECT DATENAME(dw, DATEADD(d, -ix, GETDATE())), ix+1 FROM cteCount WHERE ix<30
)
SELECT dw, COUNT(1) cnt FROM cteCount GROUP BY dw

【讨论】:

    【解决方案3】:

    几个解决方案:

    SELECT ... From ... WHERE date > DATEADD(year, -1, GETDATE())
    

    另外,我认为这个语句适用于 MySQL:

    select date_sub(now(),interval 30 day)as Datebefore30days;
    

    【讨论】:

      【解决方案4】:

      嗯,有几种方法可以做到这一点。

      1. 您可以使用循环和 INSERT 语句填充临时表,然后选择表的内容。实际上,您可以创建一个表值 UDF 来执行此操作。
      2. 您还可以创建 30 条 SELECT 语句,然后将它们全部联合起来。但是,坦率地说,我认为您最好选择选项 1。

      ETA:考虑一下,如果您只需要过去 30 天中一周中的每一天的数量,您可能只需通过一些数学运算就可以做到这一点,而无需返回 30 条记录。

      在任何 30 天的时间段内,一周中的每一天都有 4 次实例,外加 2 天。所以你真正需要的是知道你月经的第一天和第二天是一周中的哪一天。一周中的那些日子有 5 个实例。

      【讨论】:

        【解决方案5】:

        我很懒,只是加载一个临时表,然后在该临时表上通过 select 进行分组

        DECLARE @tmpDates TABLE (calDate DATETIME)
        DECLARE @beginDate DATETIME
        SET @beginDate = DATEADD(day,-30,GETDATE())
        WHILE @beginDate < GETDATE()
        BEGIN
            INSERT INTO @tmpDates ([calDate]) VALUES (@beginDate)
            SET @beginDate = DATEADD(DAY,1,@beginDate)
        END
        
        
        SELECT DATEPART(dw,[calDate]) AS [weekDay], COUNT(1) AS [dayCount]
        FROM @tmpDates
        GROUP BY DATEPART(dw,[calDate])
        

        【讨论】:

          【解决方案6】:

          过去 30 天内一周中的每一天被击中的次数:

          SELECT DATENAME(dw,GETDATE())+' 5 times' as results
          UNION ALL
          SELECT DATENAME(dw,DATEADD(day,-1,GETDATE()))+' 5 times'
          UNION ALL
          SELECT DATENAME(dw,DATEADD(day,-2,GETDATE()))+' 4 times'
          UNION ALL
          SELECT DATENAME(dw,DATEADD(day,-3,GETDATE()))+' 4 times'
          UNION ALL
          SELECT DATENAME(dw,DATEADD(day,-4,GETDATE()))+' 4 times'
          UNION ALL
          SELECT DATENAME(dw,DATEADD(day,-5,GETDATE()))+' 4 times'
          UNION ALL
          SELECT DATENAME(dw,DATEADD(day,-6,GETDATE()))+' 4 times'
          

          这实际上是关于将 30 除以 7


          这给了我

          results
          Thursday 5 times
          Wednesday 5 times
          Tuesday 4 times
          Monday 4 times
          Sunday 4 times
          Saturday 4 times
          Friday 4 times
          

          【讨论】:

          • 不寻常且...正确。 :) 但如果我是你,我会将其参数化以显示结果是如何获得的。
          • 我的意思是,在脚本本身中显示它,而不仅仅是在答案中口头表达。 :)
          • @Andriy - 不确定你的意思......你想要内联 cmets?另外,如果正确,为什么不投票? :D
          • 不赞成,因为是您解决了问题(执行了实际计算),而不是您的脚本。 :) 我认为最好将计算包含在脚本中,而不是现成的答案。
          • @Hogan:进一步澄清为什么我认为应该包括计算:30 很容易变成 50 或 100。也就是说,它可能只是一个参数,在这种情况下,计算将只是 必须被包括在内。
          猜你喜欢
          • 1970-01-01
          • 2016-06-17
          • 1970-01-01
          • 1970-01-01
          • 2016-11-30
          • 2013-12-29
          • 2013-07-08
          • 1970-01-01
          • 2013-08-30
          相关资源
          最近更新 更多