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

Brann
fuente

Respuestas:

604
SELECT DATEADD(month, DATEDIFF(month, 0, @mydate), 0) AS StartOfMonth
LukeH
fuente
63
Cabe señalar que el error mencionado por Martin Smith "solo" puede afectar el rendimiento, no la corrección.
Olson.dev
14
Aquí hay una explicación de por qué y cómo funciona esto .
RubberDuck
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)
Jithin Shaji
fuente
63

A partir de SQL Server 2012:

SELECT DATEADD(DAY,1,EOMONTH(@mydate,-1))
Marcos Krucken
fuente
11
Esto parece funcionar solo en 2012 y posteriores. msdn.microsoft.com/en-us/library/hh213020.aspx
Josh Yeager
1
Tiene la ventaja de que menciona la fecha de origen solo una vez, por lo que es más ordenado si se deriva de una llamada de función.
Ian Horwill
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)
Mayonesa
fuente
10

Consulta simple:

SELECT DATEADD(m, DATEDIFF(m, 0, GETDATE()), 0) 
-- Instead of GetDate you can put any date.
Abhishek Gupta
fuente
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
paloma
fuente
4

Esto también funciona:

    SELECT DATEADD(DAY,(DATEPART(DAY,@mydate)-1)*(-1),@mydate) AS FirstOfMonth
Alan Burstein
fuente
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)
adnan umar
fuente
3

Primer y último día del mes actual:

select dateadd(mm, -1,dateadd(dd, +1, eomonth(getdate()))) as FirstDay, 
eomonth(getdate()) as LastDay
nicolai koroslev
fuente
2
SELECT @myDate - DAY(@myDate) + 1
PoloSoares
fuente
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
kaub0st3r
fuente
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;
Ariel T
fuente
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!

Eli
fuente
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.

Ang Li
fuente
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'
Pradeep Thakur
fuente
1

Si usa SQL Server 2012 o superior;

SELECT DATEADD(MONTH, -1, DATEADD(DAY, 1, EOMONTH(GETDATE())))
Lankymart
fuente
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))
Brian Widdoes
fuente
1

Intente ejecutar la siguiente consulta:

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

divya
fuente
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

Tushar
fuente
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.

Sayka
fuente
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')
Gelatina
fuente
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)
wayner
fuente
0

Me gusta usar FORMAT, incluso puedes especificar una hora

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

En SQL Server 2012,

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

 select DATEADD(Month,1,getdate())-DATEPART(day, getdate())
BornToCode
fuente
0

Esta consulta debería funcionar muy bien en MySQL:

SELECT concat(left(curdate(),7),'-01') 
usuario11869348
fuente
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'
chimpancé
fuente
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
rinku Choudhary
fuente
-3

Así es como lo haría en MySQL:

  select DATE_FORMAT(NOW(), '%Y-%m-1')
jsarma
fuente
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