【问题标题】:WHERE Clause to find all records in a specific monthWHERE 子句查找特定月份的所有记录
【发布时间】:2010-10-25 11:21:51
【问题描述】:

我希望能够为存储过程提供月份和年份,并让它返回该月份发生的所有事情,我该怎么做,因为我无法比较某些月份的天数等?

最好的方法是什么?我可以要求根据年份和月份进行比较吗?

谢谢。

【问题讨论】:

    标签: sql sql-server-2008


    【解决方案1】:

    我认为您正在寻找的功能是MONTH(date)。您可能也想使用'YEAR'

    假设您有一个名为things 的表,如下所示:

    id happend_at
    -- ----------------
    1  2009-01-01 12:08
    2  2009-02-01 12:00
    3  2009-01-12 09:40
    4  2009-01-29 17:55
    

    假设您要执行以查找在 2009/01(2009 年 1 月)月份具有 happened_at 的所有记录。 SQL 查询将是:

    SELECT id FROM things 
       WHERE MONTH(happened_at) = 1 AND YEAR(happened_at) = 2009
    

    哪个会返回:

    id
    ---
    1
    3
    4
    

    【讨论】:

    • 确实!对于任何感兴趣的人,“DAY、MONTH 和 YEAR 函数分别是 DATEPART(dd, date)、DATEPART(mm, date) 和 DATEPART(yy, date) 的同义词。”
    【解决方案2】:

    使用大多数回复中建议的 MONTH 和 YEAR 函数的缺点是 SQL Server 将无法使用您的日期列上可能存在的任何索引。这可能会影响大型表的性能。

    我倾向于将 DATETIME 值(例如 @StartDate)传递给代表您感兴趣的月份的第一天的存储过程。

    然后你可以使用

    SELECT ... FROM ...
    WHERE DateColumn >= @StartDate 
    AND DateColumn < DATEADD(month, 1, @StartDate)
    

    如果您必须将月份和年份作为单独的参数传递给存储过程,您可以使用 CAST 和 CONVERT 生成一个表示该月第一天的 DATETIME,然后按上述方法进行操作。如果你这样做,我建议编写一个从整数年、月、日值生成 DATETIME 的函数,例如以下来自a SQL Server blog

    create function Date(@Year int, @Month int, @Day int)
    returns datetime
    as
        begin
        return dateadd(month,((@Year-1900)*12)+@Month-1,@Day-1)
        end
    go
    

    然后查询变为:

    SELECT ... FROM ...
    WHERE DateColumn >= Date(@Year,@Month,1)
    AND DateColumn < DATEADD(month, 1, Date(@Year,@Month,1))
    

    【讨论】:

    • 是的,我同意@joe “使用大多数回复中建议的 MONTH 和 YEAR 函数的缺点是 SQL Server 将无法使用您的日期列上可能存在的任何索引。这会影响大型表的性能。”
    • 我可以添加一些东西吗?如果您在参数中声明 '@StartDate,那么我也会声明 '@EndDate 并将 DATEADD 放在那里,而不是让 SQL 对每一行进行数学运算。
    • @DataGirl - 有趣的一点。我曾假设 DATEADD 函数将被视为运行时常量并且只评估一次。如果对此有疑问,声明 @EndDate 将使其明确。
    【解决方案3】:

    更多关于oracle db的提示非常简单。你也可以使用to_char函数,看:

    月份:

    to_char(happened_at , 'MM') = 01

    年份:
    to_char(happened_at , 'YYYY') = 2009

    对于一天:
    to_char(happened_at , 'DD') = 01

    to_char 函数由 sql 语言支持,而不是由一个特定的数据库支持。

    希望对大家有所帮助...

    腹肌!

    【讨论】:

    • 我的印象是这只适用于 Oracle,它非常具体。 SQL Server 肯定不支持。
    【解决方案4】:

    作为 MONTH 和 YEAR 函数的替代方法,常规 WHERE 子句也可以使用:

    select *
    from yourtable
    where '2009-01-01' <= datecolumn and datecolumn < '2009-02-01'
    

    【讨论】:

      【解决方案5】:

      如果您使用的是 SQL Server,请查看 DATEPART。

      http://msdn.microsoft.com/en-us/library/ms174420(SQL.90).aspx

      DATEPART(mm, [您正在查看的日期])

      然后你就可以使用普通的整数逻辑了。年份相同,只需使用 yy 而不是 mm。

      【讨论】:

        【解决方案6】:

        我可以要求根据年份和月份进行比较吗?

        你可以。这是一个使用 AdventureWorks 示例数据库的简单示例...

        DECLARE @Year       INT
        DECLARE @Month      INT
        
        SET @Year = 2002
        SET @Month = 6
        
        SELECT 
            [pch].* 
        FROM 
            [Production].[ProductCostHistory]   pch
        WHERE
            YEAR([pch].[ModifiedDate]) = @Year
        AND MONTH([pch].[ModifiedDate]) = @Month
        

        【讨论】:

          【解决方案7】:

          我发现将值作为时间数据类型(例如DATETIME)传递然后使用时间功能(特别是DATEADDDATEPART)来查找该期间的开始和结束日期更容易,在这种情况下这个月,例如这会找到当前月份的开始日期和结束日期对,只需将 CURRENT_TIMESTAMP 替换为 DATETIME 类型的参数(注意 1990-01-01 值完全是任意的):

          SELECT DATEADD(M, 
                    DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
                    '1990-01-01T00:00:00.000'), 
                 DATEADD(M, 
                    DATEDIFF(M, '1990-01-01T00:00:00.000', CURRENT_TIMESTAMP), 
                    '1990-01-31T23:59:59.997')
          

          【讨论】:

            【解决方案8】:

            应该这样做:

            select * from yourtable where datepart(month,field) = @month and datepart(year,field) = @year
            

            或者,您可以在创建记录时将月份和年份分成各自的列,然后根据它们进行选择。

            伊恩

            【讨论】:

              【解决方案9】:

              一种方法是创建一个表示月份第一天的变量(即 2009 年 5 月 1 日),将其传递到 proc 或构建它(连接月/1/年)。然后使用 DateDiff 函数。

              WHERE DateDiff(m,@Date,DateField) = 0
              

              这将返回具有匹配月份和年份的任何内容。

              【讨论】:

                【解决方案10】:
                SELECT * FROM yourtable WHERE yourtimestampfield LIKE 'AAAA-MM%';
                

                AAAA 是您想要的年份,MM 是您想要的月份

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2015-05-30
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多