我只需要选择给定datetime变量的月份的第一天。

我知道使用这种代码非常容易:

select CAST(CAST(YEAR(@mydate) AS VARCHAR(4)) 
+ '/' + CAST(MONTH(@mydate) AS VARCHAR(2)) + '/01' AS DATETIME)


但这不是很优雅,也可能不太快。

有更好的方法吗?我正在使用SQL Server2008。

#1 楼

SELECT DATEADD(month, DATEDIFF(month, 0, @mydate), 0) AS StartOfMonth


评论


如果使用此方法,则需要注意基数估计错误

–马丁·史密斯
13年8月15日在14:01

应当指出,马丁·史密斯(Martin Smith)提到的错误只能“影响”性能,而不能影响正确性。

– Olson.dev
2014年5月5日在21:19

这是为什么和为什么的解释。

–RubberDuck
2014年10月15日19:24

如果有人想知道SELECT EOMONTH(@mydate)AS EndOfMonth会给您该月的最后一天。

–hallizh
15年11月3日,13:47

我如何确定所指出的基数估计错误是否会影响我?它在2010年被标记为已修复。这是否意味着只有SQL Server 2012和更高版本才是安全的,还是可能对2008服务器进行了修补?

–乔恩
17年5月5日在18:05

#2 楼

除了上述所有答案外,还基于sql 2012

SELECT DATEFROMPARTS(YEAR(@mydate),MONTH(@mydate),1)

中引入的功能的方式

#3 楼

从SQL Server 2012开始:

SELECT DATEADD(DAY,1,EOMONTH(@mydate,-1))


评论


这似乎仅适用于2012年及更高版本。 msdn.microsoft.com/zh-CN/library/hh213020.aspx

–乔什·耶格(Josh Yeager)
2014年9月1日15:56



优点是它仅提及源日期一次,因此,如果源日期是从函数调用派生的,则更加整洁。

–伊恩·霍威尔(Ian Horwill)
18-10-4在11:12

#4 楼

将字符串(即“ 2009年5月1日”)强制转换为日期时间肯定更清晰,但我们发现前段代码可以返回本月的第一天。 />

#5 楼

简单查询:

SELECT DATEADD(m, DATEDIFF(m, 0, GETDATE()), 0) 
-- Instead of GetDate you can put any date.


#6 楼

它可能很快。为什么不将其创建为sql函数。

CREATE FUNCTION [dbo].[GetFirstDayOfMonth] ( @InputDate    DATETIME )
RETURNS DATETIME
BEGIN

    RETURN CAST(CAST(YEAR(@InputDate) AS VARCHAR(4)) + '/' + 
                CAST(MONTH(@InputDate) AS VARCHAR(2)) + '/01' AS DATETIME)

END
GO


#7 楼

这也适用:

    SELECT DATEADD(DAY,(DATEPART(DAY,@mydate)-1)*(-1),@mydate) AS FirstOfMonth


#8 楼

本月的第一天和最后一天:

 select dateadd(mm, -1,dateadd(dd, +1, eomonth(getdate()))) as FirstDay, 
eomonth(getdate()) as LastDay
 


#9 楼

SELECT @myDate - DAY(@myDate) + 1


评论


真正简单而优雅的解决方案,但请记住,如果在变量中指定了日期,则它还会返回日期的时间部分。

– Kuklei
14-10-17在15:52

我无法使它正常工作。除了多余的右括号外,我还会收到此错误:操作数类型冲突:日期与int不兼容。我猜是因为您要在日期上使用-运算符?

–山姆
2014年12月10日下午3:26

我不知道它在性能方面有多好,但确实可以完成工作。

–沙币
15-10-20在15:39

@Sam,您会发生冲突,因为简单的算术(+,-)在日期时间有效,而不是日期有效。

– darlove
19/12/11在17:43

#10 楼

请使用此



用于Server 2012

DATEFROMPARTS(year('2015-06-30'),month('2015-06-30'),1)



在Server 2012之前

select  cast(cast(year('2015-06-30') as varchar(4))+'-'+ cast(month('2015-06-30') as varchar(2))+'-01' as smalldatetime)




#11 楼

这可能是一个新函数,但您也可以使用旧函数:

select DATEFROMPARTS(year(@mydate),month(@mydate),'01')


如果变量中的日期例如是'2017-10-29'
,它将返回一个'2017-10-01'的日期

https://docs.microsoft.com/zh-cn/sql/t-sql/functions/datefromparts-transact-sql?view=sql-server-ver15

#12 楼

----Last Day of Previous Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE()),0))
LastDay_PreviousMonth
----Last Day of Current Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+1,0))
LastDay_CurrentMonth
----Last Day of Next Month
SELECT DATEADD(s,-1,DATEADD(mm, DATEDIFF(m,0,GETDATE())+2,0))
LastDay_NextMonth


评论


但是OP正在寻找该月的第一天。对于最后一天,您可以只使用EOMONTH()-自2012年以来一直采用这种方式。

–deutschZuid
19年2月14日在21:51

#13 楼

未来的Googlers,在MySQL上,请尝试以下操作:

select date_sub(ref_date, interval day(ref_date)-1 day) as day1;


评论


这是一个sql服务器问题,date_sub和interval是mysql。

– OGHaza
2013年12月12日17:31



很好,我编辑了回复。我认为它仍然与线程相关。

– Ariel T
13年12月13日在15:55

#14 楼

我使用GETDATE()作为要使用的日期,您可以将其替换为所需的日期。
这是它的工作原理:首先,我们将日期格式化为YYYYMMDD ...格式,将其截断以仅保留最左边的6个字符,以便仅保留YYYYMM部分,然后将“ 01”添加为月份-瞧!您有当月的第一天。

SELECT CAST(CONVERT(VARCHAR(6),GETDATE(),112) +'01' AS DATETIME) AS StartOfMonth


顺便说一句,这个表现很棒!

#15 楼

如果您今天就在使用SQL Server 2012或更高版本进行查看,则可以使用EOMONTH函数,该函数使事情变得更容易:

您想要的日期变量。

#16 楼

在这里,我们可以使用下面的查询查询该月的第一个日期和该月的最后一个日期。

#17 楼

如果使用SQL Server 2012或更高版本;

SELECT DATEADD(MONTH, -1, DATEADD(DAY, 1, EOMONTH(GETDATE())))


#18 楼

DECLARE @startofmonth date
SET @startofmonth = DATEADD(dd,1,EOMONTH(Getdate(),-2))


-2将带您上个月的第一天。即getdate()是10/15/18。您的结果将是9/1/18。更改为-1,结果将为10/1/18。 0表示下个月的开始日期,2018年11月1日。等等。

#19 楼

尝试执行以下查询:

SELECT DATE_ADD(DATE_ADD(LAST_DAY(CURRENT_DATE-INTERVAL 1 DAY),INTERVAL 1 DAY),INTERVAL -1 MONTH)

#20 楼

选择CONVERT(date,DATEADD(dd,-(DATEPART(dd,getdate())-1),getdate()),120)

此函数将为您提供开始日期的日期部分月

#21 楼

SELECT DATEADD (DAY, -1 * (DAY(GETDATE()) - 1), GETDATE())


..................................................... .....................................

如果您不想要时间,请将其转换为DATE或想要将时间设置为0:00:00,将其转换为DATE然后再返回DATETIME。 >

#22 楼

我个人建议使用下面的sql,因为当我在condition子句中尝试使用date函数时,它会大大降低我的查询速度。

无论如何都可以尝试一下。

select CONCAT(DATEPART(YYYY,@mydate),'-',DATEPART(MM,@mydate),'-01')


#23 楼

不是要与这里的任何优秀人才竞争,而是一个简单的建议,与上面接受的答案稍有不同。

#24 楼

我喜欢使用FORMAT,甚至可以指定时间

SELECT FORMAT(@myDate,'yyyy-MM-01 06:00') first_of_a_month


#25 楼

在Sql Server 2012中,

 select getdate()-DATEPART(day, getdate())+1

 select DATEADD(Month,1,getdate())-DATEPART(day, getdate())


#26 楼

此查询在MySQL上应该可以很好地工作:

SELECT concat(left(curdate(),7),'-01') 


#27 楼

对于仍在寻找答案的任何人,这就像一个咒语,并且消除了任何添加的日期。时间戳是可选的(如果需要指定时间戳),但时间戳也可以不使用。

#28 楼

在SQL中作为参数传递的日期中获取第一个日期和最后一个日期

#29 楼

那有什么不同呢!使用格式。
DECLARE @Date Date =GetDate();
SELECT CONVERT(Date,Format(@Date,'yyyyMM01'));

如果要转换为日期列或变量,可以删除转换
DECLARE @Date Date =GetDate();
SELECT @Date =Format(@Date,'yyyyMM01');
SELECT [Date]=@Date

玩得开心:)

#30 楼

在MySQL中的操作方法如下:

  select DATE_FORMAT(NOW(), '%Y-%m-1')


评论


请指定这不是sql-server答案,但仅适用于MySQL。

– Kuklei
2014-10-17 15:35



对于SQL Server,可以使用SELECT FORMAT(GETDATE(),'yyyy-MM-01')

– NASSER
'18 -10-31在12:25

不要鼓励人们将日期格式化为字符串,只是为了做一些可以并且应该以数字方式完成的事情。这就像在说:“您可以将数字格式化为字符串,将除最后两位之外的所有数字都进行子字符串化,然后将其连接为“ 00”,从而将数字四舍五入到最接近的100

–凯乌斯·贾德(Caius Jard)
20 Mar 9 '20 at 20:18