Как выбрать первый день месяца в SQL?


308

Мне просто нужно выбрать первый день месяца для данной переменной datetime.

Я знаю, что это довольно легко сделать с помощью такого кода:

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


34
В случае, если кто-то задается вопросом SELECT EOMONTH(@mydate) AS EndOfMonth, даст вам последний день месяца.
Халлиж

3
Как я могу определить, повлияет ли отмеченная ошибка оценки количества элементов на меня? Он помечен как исправленный в 2010 году. Означает ли это, что только SQL Server 2012 и новее безопасны, или возможно, что сервер 2008 был исправлен?
Джон

134

В дополнение ко всему ответу выше, способ, основанный на функции, введенной в sql 2012

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

63

Начиная с SQL Server 2012:

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

11
Похоже, что это работает только в 2012 году и позже. msdn.microsoft.com/en-us/library/hh213020.aspx
Джош Йегер

1
Преимущество в том, что он упоминает дату источника только один раз, поэтому лучше, если она получена из вызова функции.
Ян Хорвилл,

14

Приведение строки (то есть «01.05.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

Действительно простое и элегантное решение, но имейте в виду, что оно также возвращает временную часть даты, если она указана в переменной.
куклей

Я не мог заставить это работать. Помимо дополнительной закрывающей скобки, я получаю эту ошибку: Operand type clash: date is incompatible with int. Я думаю, это потому, что вы пытаетесь использовать -оператора на свидание?
Сэм

Я не знаю, насколько это хорошо с точки зрения производительности, но это, безусловно, делает свою работу.
Salcoin

@ Сэм, у вас конфликт, потому что простая арифметика (+, -) работает с датами, а не с датами.
дорогая

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

Но ОП ищет первый день месяца. В последний день вы могли бы просто использовать EOMONTH () - так было с 2012 года.
deutschZuid


1

Будущие Google, на MySQL, попробуйте это:

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

3
Это sql-serverвопрос date_subи intervalесть mysql.
О.Г.Газа

Хорошо, точка, я отредактировал ответ. Я думаю, что это все еще актуально для потока.
Ариэль Т

1

Я использовал GETDATE () в качестве даты для работы, вы можете заменить ее на нужную вам дату.
Вот как это работает: сначала мы форматируем дату в формате ГГГГММДД ... усечая ее, сохраняя только 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

Если используется SQL Server 2012 или выше;

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

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

-2 даст вам первый день прошлого месяца. то есть, getdate () - 15.10.18. Ваши результаты будут 01.09.18. Измените на -1, и ваши результаты будут 10/1/18. 0 будет началом следующего месяца, 1.11.08 .. и т. Д.

или

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 (дата, 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

Этот запрос должен очень хорошо работать на MySQL:

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

0

Для тех, кто все еще ищет ответ, это работает как шарм и устраняет любые даты. Временная метка является необязательной, если она требует указания, но работает и без нее.

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-сервера, а работает только на MySQL.
куклей

Для SQL Server вы можете использоватьSELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER

Не поощряйте людей форматировать даты в строки, просто чтобы делать то, что можно и нужно делать численно. Это все равно, что сказать: «Вы можете округлить число до ближайших 100, отформатировав его в строку, подставив из него все, кроме двух последних цифр, и конкатенируя в« 00 »»
Caius Jard
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.