【问题标题】:days of the month一个月的几天
【发布时间】:2013-01-29 05:51:31
【问题描述】:

我知道这听起来很荒谬...我知道...但我希望能够选择每月的前 7 天并获得这样的结果。

这就是我所拥有的:

SELECT row_number () OVER (ORDER BY DateD), * FROM (SELECT DATENAME (dw, GETDATE ()) AS 'DateName', getdate () AS 'DateD' 联盟 选择 DATENAME (dw, GETDATE () + 1) AS 'DateName', getdate () + 1 AS 'DateD' 联盟 选择 DATENAME (dw, GETDATE () + 2) AS 'DateName', getdate () + 2 AS 'DateD' 联盟 选择日期名称(dw,GETDATE()+ 3)作为'日期名称', getdate () + 3 AS 'DateD' 联盟 选择 DATENAME (dw, GETDATE () + 4) AS 'DateName', getdate () + 4 AS 'DateD' 联盟 选择日期名称(dw,GETDATE()+ 5)作为'日期名称', getdate () + 5 AS 'DateD' 联盟 选择 DATENAME (dw, GETDATE () + 6) AS 'DateName', getdate () + 6 AS 'DateD') 查询表

【问题讨论】:

  • 顺便说一句,我建议不要使用AS 'alias' 语法。某些形式已被弃用,无论如何它令人困惑,因为许多人看到它并认为它是一个字符串。对需要转义的标识符使用[square brackets],而不是字符串分隔符。

标签: sql-server


【解决方案1】:

这是获取当月 @n 天数的更简单方法。如果您需要在不同的月份使用它,只需将 GETDATE() 替换为表示您想要的月份内任何日期时间值的变量即可。

;WITH x AS 
(
  SELECT TOP (@n) n = ROW_NUMBER() OVER (ORDER BY [object_id])
  FROM sys.all_objects
),
y(d,n) AS
(
  SELECT DATEADD(DAY, n-1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)),
   n FROM x
)
SELECT 
  RowNumber = n, 
  [Weekday] = DATENAME(WEEKDAY, d), 
  [Date_In_Ambiguous_Format] = CONVERT(CHAR(10), d, 101),
  [Date_In_Proper_DataType] = d
FROM y;

请参阅此博客系列关于无循环和无重复代码的生成集:

http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-1
http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-2
http://www.sqlperformance.com/2013/01/t-sql-queries/generate-a-set-3

【讨论】:

  • @bluefeet 美丽在情人眼中。 :-) 我的代码要少得多,但如果读者不检查博客文章,可能需要相当多的解释......
【解决方案2】:

这是一个非常丑陋的查询,它会为您提供结果:

SELECT row_number () OVER (ORDER BY DateD), *
FROM 
(
    SELECT DATENAME (dw, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) AS 'DateName', 
        DATEADD(month, DATEDIFF(month, 0, getdate()), 0) AS 'DateD'
    UNION
    SELECT DATENAME (dw, DateAdd(day, 1, DATEADD(month, DATEDIFF(month, 0, getdate()), 0))) AS 'DateName',
           DateAdd(day, 1, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) AS 'DateD'
    UNION
    SELECT DATENAME (dw, DateAdd(day, 2, DATEADD(month, DATEDIFF(month, 0, getdate()), 0))) AS 'DateName',
           DateAdd(day, 2, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) AS 'DateD'
    UNION
    SELECT DATENAME (dw, DateAdd(day, 3, DATEADD(month, DATEDIFF(month, 0, getdate()), 0))) AS 'DateName',
           DateAdd(day, 3, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) AS 'DateD'
    UNION
    SELECT DATENAME (dw, DateAdd(day, 4, DATEADD(month, DATEDIFF(month, 0, getdate()), 0))) AS 'DateName',
           DateAdd(day, 4, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) AS 'DateD'
    UNION
    SELECT DATENAME (dw, DateAdd(day, 5, DATEADD(month, DATEDIFF(month, 0, getdate()), 0))) AS 'DateName',
           DateAdd(day, 5, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) AS 'DateD'
    UNION
    SELECT DATENAME (dw, DateAdd(day, 6, DATEADD(month, DATEDIFF(month, 0, getdate()), 0))) AS 'DateName',
           DateAdd(day, 6, DATEADD(month, DATEDIFF(month, 0, getdate()), 0)) AS 'DateD'
) queryTable

SQL Fiddle with Demo

【讨论】:

    【解决方案3】:

    你可以使用这个递归 CTE:

    WITH dayscte ( d ) 
         AS (SELECT DATEADD(DAY, 0, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)) AS d 
             UNION ALL 
             SELECT Dateadd(d, 1, d) 
             FROM   dayscte 
             WHERE  Datepart(day, d) < 7)  -- number of days you want
    SELECT d, 
           Datepart(wk, d) AS week_number, 
           Datename(dw, d) AS day_name, 
           Datename(m, d)  AS month_name, 
           Datename(q, d)  AS [quarter] 
    FROM   dayscte 
    OPTION (maxrecursion 800); 
    

    Demo

    【讨论】:

    • 仅供参考,递归 CTE 适用于小集合,但随着集合变大,它们的成本会成倍增加(请参阅我的博客系列以获取证据)。
    • @AaronBertrand:谢谢,我提到它是因为 OP 只想要给定月份的前 7 天。
    • 当然,我只是添加评论,因为未来的读者可能想要整个月、6 个月等。
    【解决方案4】:
    WITH Dates AS
    (
        SELECT DATEADD(DAY, - (DATEPART(DAY, GETDATE()) - 1), CONVERT(VARCHAR, GETDATE(), 101)) as DateDay
        UNION ALL
        SELECT DateDay + 1
        FROM Dates
        WHERE DATEPART(DAY, DateDay) < 7
    )
    
    SELECT
        DATEPART(DAY, DateDay),
        DATENAME(DW, DateDay),
        DateDay
    FROM Dates
    

    【讨论】:

      【解决方案5】:

      使用 SQL Server,您可以查询 master..spt_values 以获取数字列表(不是完整的数字列表,但肯定是 1 到 7):

      SELECT 
         row_number () OVER (ORDER BY Number) as Row, 
         DATENAME (dw,CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GetDate())-Number),GetDate()),101) ) AS DtName,
         CONVERT(VARCHAR, CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(GetDate())-Number),GetDate()),101), 101) As Dt
      FROM (SELECT Number FROM master..spt_values WHERE Number BETWEEN 1 AND 7 AND Type = 'P') t
      

      只是另一种方法——玩得开心!这是Fiddle

      祝你好运。

      【讨论】:

        猜你喜欢
        • 2021-07-30
        • 1970-01-01
        • 2011-09-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-28
        • 1970-01-01
        • 2017-10-22
        相关资源
        最近更新 更多