SQLで月の最初の日を選択するにはどうすればよいですか?


308

特定の日時変数の月の最初の日を選択するだけです。

この種のコードを使用するのは非常に簡単です。

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

しかし、これはあまりエレガントではなく、おそらくあまり高速でもありません。

これを行うより良い方法はありますか?SQL Server 2008を使用しています。

回答:


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


63
マーティン・スミスによって言及されたバグは、正確さにではなく、パフォーマンスに「のみ」影響を与える可能性があることに注意してください。
Olson.dev 2014年


34
誰かが不思議に思っている場合SELECT EOMONTH(@mydate) AS EndOfMonthは、月の最後の日を与えます。
Hallizh

3
示されたカーディナリティ推定バグが私に影響を与えるかどうかをどのように判断できますか?それは2010年に修正済みとしてマークされています。それはSQL Server 2012以降のみが安全であることを意味しますか、それとも2008サーバーにパッチが適用されている可能性がありますか?
ジョン

134

上記のすべての回答に加えて、で導入された関数に基づく方法 sql 2012

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


14

文字列(つまり "5/1/2009")をdatetimeにキャストする方が確かに読みやすいですが、しばらく前に、月の最初を返すコードが見つかりました...

DECLARE @Date DATETIME
//...
SELECT DATEADD(mm, DATEDIFF(mm,0,@Date), 0)


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


3

こちらをご利用ください

  1. サーバー2012

    DATEFROMPARTS(year('2015-06-30'),month('2015-06-30'),1)
  2. Server 2012より前

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


2
SELECT @myDate - DAY(@myDate) + 1

本当にシンプルでエレガントなソリューションですが、変数で指定されている場合、これは日付の時刻部分も返すことに注意してください。
kuklei 2014年

これを機能させることができませんでした。追加の閉じ括弧のほかに、次のエラーが発生しますOperand type clash: date is incompatible with int。あなたが-日付で演算子を使用しようとしているからだと思いますか?
2014

パフォーマンスの点でどれほど優れているかはわかりませんが、確かにうまくいきます。
salcoin

@Sam、単純な算術(+、-)は日付ではなく日時で機能するため、衝突が発生します。
darlove

2
----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


1

MySQLで将来のグーグル、これを試してください:

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

3
これはsql-server、質問、date_subおよびintervalですmysql
OGHaza

いいですね、回答を編集しました。それはまだスレッドに関連していると思います。
アリエルT

1

使用する日付としてGETDATE()を使用しましたが、必要な日付に置き換えることができます。
これがどのように機能するかです:最初に日付をYYYYMMDDでフォーマットします... YYYYMMの部分だけを保持するために、左端の6文字だけを保持するように切り捨てます。次に、月に「01」を追加します。あなたは今月の最初の日を持っています。

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

ところで、これでパフォーマンスは素晴らしいです!


1

今日これを見ていて、SQL Server 2012以降を使用している場合、EOMONTH関数があり、物事をより簡単にします。

SELECT DATEADD(day, 1, EOMONTH(DATEADD(month, -1, GETDATE()))) as firstdateofmonth

GETDATE()は、任意の日付変数で変更できます。


1

ここでは、月の最初の日付と月の最後の日付に対して以下のクエリを使用できます。

SELECT DATEADD(DAY,1,EOMONTH(Getdate(),-1)) as 'FD',Cast(Getdate()-1 as Date)
as 'LD'


1
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日などです。

または

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

1

次のクエリを実行してみてください。

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


0

CONVERT(date、DATEADD(dd、-(DATEPART(dd、getdate())-1)、getdate())、120)を選択します

この関数は、月の開始日の日付部分を提供します


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

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

時間を必要としない場合は、それをDATEに変換するか、時間を0:00:00にしたい場合は、DATEに変換してからDATETIMEに戻します。

SELECT CONVERT (DATETIME,  
CONVERT (DATE, DATEADD (DAY, -1 * (DAY(GETDATE()) - 1),
GETDATE())))

GETDATE()を必要な日付に変更します


0

条件句で日付関数を使用しようとすると、クエリ速度が非常に遅くなるため、以下のSQLを個人的に推奨しました。

とにかくこれを試してみてください。

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

0

ここで優れたマインドと競争するのではなく、上記の受け入れられた回答とは少し異なる単純な提案。

select dateadd(day, -(datepart(day,@date)+1,@date)

0

使用FORMATしたい、時間を指定することもできます

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

0

SQL Server 2012では、

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

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


0

まだ答えを探している人にとっては、これは魅力のように機能し、dateaddsはありません。指定が必要な場合に備えて、タイムスタンプはオプションですが、なくても機能します。

SELECT left(convert(varchar, getdate(),23),7)+'-01 00:00:00'

0

SQLのパラメーターとして渡す日付の最初の日付と最後の日付を取得します。

     @date DATETIME
    SELECT @date = GETDATE()
    SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(@date)-1),@date),105) AS value,
    'First Day of Current Month' AS name
    UNION
    SELECT CONVERT(VARCHAR(25),DATEADD(dd,-(DAY(DATEADD(mm,1,@date))),
    DATEADD(mm,1,@date)),105),
    'Last Day of Current Month'
    GO


      **OutPut**

12/01/2019  First Day of Current Month
12/31/2019  Last Day of Current Month

-3

MySQLでこれを行う方法は次のとおりです。

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

4
これはsql-serverの回答ではなく、MySQLでのみ機能することを指定してください。
kuklei 2014年

SQL Serverの場合、使用できますSELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER 2018年

数値で実行できる、または実行する必要があることだけを行うために、日付を文字列にフォーマットすることを人々に勧めないでください。「数字を文字列にフォーマットし、最後の2桁を除いてすべてサブストリング化し、'00 'で連結することにより、数値を最も近い100に切り捨てることができる」のようなものです
Caius Jard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.