Як я можу вибрати перший день місяця в SQL?


308

Мені просто потрібно вибрати перший день місяця заданої змінної дати.

Я знаю, що це дуже просто зробити за допомогою такого коду:

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

Але це не дуже елегантно, і, мабуть, теж не дуже швидко.

Чи є кращий спосіб зробити це? Я використовую SQL Server 2008.

Відповіді:


603
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
Josh Yeager

1
Має ту перевагу, що вона згадує дату джерела лише один раз, тому акуратніше, якщо це походить від виклику функції.
Ян Хорвілл

14

Лиття рядка (тобто "5/1/2009") до дату часу, безумовно, є більш розбірливим, але ми знайшли код назад, який повернеться в першій частині місяця ...

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. До сервера 2012 року

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

3

Перший і останній день поточного місяця:

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

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

Дійсно просте та елегантне рішення, але майте на увазі, що це також повертає часову частину дати, якщо вона вказана у змінній.
kuklei

Я не міг змусити це працювати. Крім додаткової закриває дужки, я отримую цю помилку: Operand type clash: date is incompatible with int. Я думаю, це тому, що ви намагаєтесь використовувати -оператора на побачення?
Сем

Я не знаю, наскільки це добре з точки зору продуктивності, але, безумовно, це робить свою роботу.
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

Але ОП шукає перший день місяця. Останній день ви могли просто використовувати EOMONTH () - так було з 2012 року.
deutschZuid


1

Майбутні googlers на MySQL спробуйте це:

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

3
Це sql-serverпитання date_subі intervalє mysql.
OGHaza

Добре, вказуй, ​​я відредагував відповідь. Я думаю, що це все ще актуально для нитки.
Аріель Т

1

Я використовував GETDATE () як дату для роботи, ви можете замінити його на потрібну дату.
Ось як це працює: Спочатку ми відформатуємо дату у форматі YYYYMMDD ... обрізання, щоб зберегти лише шість лівих символів, щоб зберегти лише YYYYMM частину, а потім додавати "01" як місяць - і вуаля! у вас перший день поточного місяця.

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

До речі, продуктивність на цьому чудова!


1

Якщо ви сьогодні дивитесь на це і використовуєте сервер SQL 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. Ваші результати будуть 9/1/18. Змініть на -1, а результати - 01.10.18. 0 буде початком наступного місяця, 11/1/2018 .. тощо. Тощо.

або

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 2012,

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

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


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.
kuklei

Для SQL Server можна скористатисяSELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER

Не закликайте людей форматувати дати в рядки, щоб зробити щось, що можна і потрібно зробити чисельно. Це як сказати "ви можете округлити число до найближчого 100, відформатувавши його в рядок, підстрокуючи всі, крім двох останніх цифр, і об'єднавшись на" 00 ""
Кай Жард,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.