¿Cómo puedo seleccionar el primer día de un mes en SQL?


308

Solo necesito seleccionar el primer día del mes de una variable de fecha y hora dada.

Sé que es bastante fácil hacerlo usando este tipo de código:

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

Pero esto no es muy elegante, y probablemente tampoco sea muy rápido.

¿Hay una mejor manera de hacer esto? Estoy usando SQL Server 2008.

Respuestas:


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


63
Cabe señalar que el error mencionado por Martin Smith "solo" puede afectar el rendimiento, no la corrección.
Olson.dev


34
En caso de que alguien se lo pregunte, SELECT EOMONTH(@mydate) AS EndOfMonthle dará el último día del mes.
hallizh

3
¿Cómo puedo determinar si el error de estimación de cardinalidad observado me afectará? Está marcado como fijo en 2010. ¿Eso significa que solo SQL Server 2012 y versiones posteriores son seguras, o es posible que un servidor de 2008 haya sido parcheado?
Jon

134

Además de toda la respuesta anterior, una forma basada en una función introducida en sql 2012

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


14

La transmisión de una cadena (es decir, "5/1/2009") a fecha y hora es ciertamente más legible, pero encontramos un código hace un tiempo que regresaría el primero del mes ...

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

10

Consulta simple:

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

6

Probablemente sea bastante rápido. ¿Por qué no crearlo como una función 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

4

Esto también funciona:

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

3

Por favor use esto

  1. Para el servidor 2012

    DATEFROMPARTS(year('2015-06-30'),month('2015-06-30'),1)
  2. Antes del servidor 2012

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

3

Primer y último día del mes actual:

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

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

Solución realmente simple y elegante, pero tenga en cuenta que esto también devuelve la parte de tiempo de la fecha si se especifica en la variable.
kuklei

No pude hacer que esto funcione. Además del corchete de cierre adicional, me sale este error: Operand type clash: date is incompatible with int. ¿Supongo que es porque estás tratando de usar el -operador en una cita?
Sam

No sé qué tan bueno es en términos de rendimiento, pero ciertamente hace el trabajo.
salcoin

@Sam, tienes un choque porque la aritmética simple (+, -) funciona en fechas, no en fechas.
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

Pero el OP está buscando el primer día del mes. Para el último día, podría usar EOMONTH () - ha sido así desde 2012.
deutschZuid


1

Los futuros googlers, en MySQL, intenten esto:

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

3
Esta es una sql-serverpregunta, date_suby lo intervalson mysql.
OGHaza

Bien, punto, edité la respuesta. Creo que sigue siendo relevante para el hilo.
Ariel T

1

Usé GETDATE () como fecha para trabajar, puede reemplazarlo con la fecha que necesita.
Así es como funciona: Primero formateamos la fecha en AAAAMMDD ... truncando el formato para mantener solo los 6 caracteres más a la izquierda para mantener solo la porción AAAAMM, y luego agregamos '01' como el mes, ¡y listo! tienes el primer día del mes actual.

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

Por cierto, ¡el rendimiento es excelente en esto!


1

Si está viendo esto hoy y usa SQL Server 2012 o más reciente, tiene la función EOMONTH que facilita las cosas:

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

Puede cambiar GETDATE () con la variable de fecha que desee.


1

Aquí podemos usar la consulta a continuación para la primera fecha del mes y la última fecha del mes.

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

1

Si usa SQL Server 2012 o superior;

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

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

El -2 te dará el primer día del mes pasado. es decir, getdate () es 15/10/18. Sus resultados serían el 1/9/18. Cambie a -1 y sus resultados serían 1/10/18. 0 sería el inicio del próximo mes, 11/1/2018 .. etc. etc.

o

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

1

Intente ejecutar la siguiente consulta:

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


0

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

Esta función le proporcionará la fecha parte de la fecha de inicio del mes


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

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

Si no desea la hora, conviértala a DATE o si desea hacerla a las 0:00:00, Convertir a DATE y luego nuevamente a DATETIME.

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

Cambie GETDATE () a la fecha que desee.


0

Personalmente recomendé el siguiente sql porque cuando intento usar la función de fecha en la cláusula de condición, disminuye mucho la velocidad de mi consulta.

de todos modos, siéntase libre de probar esto.

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

0

No para competir con ninguna de las grandes mentes aquí, sino una simple sugerencia ligeramente diferente a la respuesta aceptada anteriormente.

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

0

Me gusta usar FORMAT, incluso puedes especificar una hora

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

0

En SQL Server 2012,

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

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

0

Esta consulta debería funcionar muy bien en MySQL:

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

0

Para cualquiera que todavía busque una respuesta, esto funciona de maravilla y elimina cualquier fecha. La marca de tiempo es opcional, en caso de que necesite especificarse, pero también funciona sin ella.

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

0

Obtenga la primera fecha y la última fecha en la fecha que pasamos como parámetro en 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

Así es como lo haría en MySQL:

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

44
Especifique que esta no es la respuesta del servidor SQL, sino que solo funciona en MySQL.
kuklei

Para SQL Server, puede usarSELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER el

No aliente a las personas a formatear fechas en cadenas solo para hacer algo que pueda y deba hacerse numéricamente. Es como decir "puedes redondear un número al 100 más cercano formateándolo en una cadena, subcadenando todos menos los dos últimos dígitos y concatenando en un '00'"
Caius Jard
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.