【发布时间】:2010-10-25 11:21:51
【问题描述】:
我希望能够为存储过程提供月份和年份,并让它返回该月份发生的所有事情,我该怎么做,因为我无法比较某些月份的天数等?
最好的方法是什么?我可以要求根据年份和月份进行比较吗?
谢谢。
【问题讨论】:
标签: sql sql-server-2008
我希望能够为存储过程提供月份和年份,并让它返回该月份发生的所有事情,我该怎么做,因为我无法比较某些月份的天数等?
最好的方法是什么?我可以要求根据年份和月份进行比较吗?
谢谢。
【问题讨论】:
标签: sql sql-server-2008
我认为您正在寻找的功能是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
【讨论】:
使用大多数回复中建议的 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))
【讨论】:
@EndDate 将使其明确。
更多关于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 语言支持,而不是由一个特定的数据库支持。
希望对大家有所帮助...
腹肌!
【讨论】:
作为 MONTH 和 YEAR 函数的替代方法,常规 WHERE 子句也可以使用:
select *
from yourtable
where '2009-01-01' <= datecolumn and datecolumn < '2009-02-01'
【讨论】:
如果您使用的是 SQL Server,请查看 DATEPART。
http://msdn.microsoft.com/en-us/library/ms174420(SQL.90).aspx
DATEPART(mm, [您正在查看的日期])
然后你就可以使用普通的整数逻辑了。年份相同,只需使用 yy 而不是 mm。
【讨论】:
我可以要求根据年份和月份进行比较吗?
你可以。这是一个使用 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
【讨论】:
我发现将值作为时间数据类型(例如DATETIME)传递然后使用时间功能(特别是DATEADD 和DATEPART)来查找该期间的开始和结束日期更容易,在这种情况下这个月,例如这会找到当前月份的开始日期和结束日期对,只需将 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')
【讨论】:
应该这样做:
select * from yourtable where datepart(month,field) = @month and datepart(year,field) = @year
或者,您可以在创建记录时将月份和年份分成各自的列,然后根据它们进行选择。
伊恩
【讨论】:
一种方法是创建一个表示月份第一天的变量(即 2009 年 5 月 1 日),将其传递到 proc 或构建它(连接月/1/年)。然后使用 DateDiff 函数。
WHERE DateDiff(m,@Date,DateField) = 0
这将返回具有匹配月份和年份的任何内容。
【讨论】:
SELECT * FROM yourtable WHERE yourtimestampfield LIKE 'AAAA-MM%';
AAAA 是您想要的年份,MM 是您想要的月份
【讨论】: