Comment puis-je sélectionner le premier jour d'un mois dans SQL?


308

J'ai juste besoin de sélectionner le premier jour du mois d'une variable datetime donnée.

Je sais que c'est assez facile à faire en utilisant ce type de code:

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

Mais ce n'est pas très élégant, et probablement pas très rapide non plus.

Y a-t-il une meilleure manière de faire cela? J'utilise SQL Server 2008.

Réponses:


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


63
Il convient de noter que le bogue mentionné par Martin Smith peut "uniquement" affecter les performances, pas la correction.
Olson.dev


34
SELECT EOMONTH(@mydate) AS EndOfMonthSi quelqu'un se demande, il vous donnera le dernier jour du mois.
hallizh

3
Comment puis-je déterminer si le bogue d'estimation de cardinalité noté m'affectera? Il est marqué comme corrigé en 2010. Cela signifie-t-il que seuls SQL Server 2012 et les versions plus récentes sont sûrs, ou est-il possible qu'un serveur 2008 ait été corrigé?
Jon

134

En plus de toutes les réponses ci-dessus, un moyen basé sur une fonction introduite dans sql 2012

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


14

La conversion d'une chaîne (c'est-à-dire "5/1/2009") en datetime est certainement plus lisible mais nous avons trouvé du code il y a quelque temps qui retournerait le premier du mois ...

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

10

Requête simple:

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

6

C'est probablement assez rapide. Pourquoi ne pas le créer en tant que fonction 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

Cela fonctionne aussi:

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

3

Veuillez utiliser ceci

  1. Pour Server 2012

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

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

3

Premier et dernier jour du mois en cours:

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

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

Solution vraiment simple et élégante, mais gardez à l'esprit que cela renvoie également la partie heure de la date si elle est spécifiée dans la variable.
kuklei

Je n'ai pas pu faire fonctionner ça. Outre le support de fermeture supplémentaire, je reçois cette erreur: Operand type clash: date is incompatible with int. Je suppose que c'est parce que vous essayez d'utiliser l' -opérateur à une date?
Sam

Je ne sais pas à quel point c'est bon en termes de performances, mais ça fait certainement l'affaire.
salcoin

@Sam, vous avez un conflit car la simple arithmétique (+, -) fonctionne sur les heures, pas sur les dates.
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

Mais l'OP recherche le premier jour du mois. Pour le dernier jour, vous pouvez simplement utiliser EOMONTH () - a été ainsi depuis 2012.
deutschZuid


1

Les futurs googleurs, sur MySQL, essayez ceci:

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

3
C'est une sql-serverquestion, date_subet le intervalsont mysql.
OGHaza

Bon, point, j'ai édité la réponse. Je pense que c'est toujours pertinent pour le fil.
Ariel T

1

J'ai utilisé GETDATE () comme date de travail, vous pouvez le remplacer par la date dont vous avez besoin.
Voici comment cela fonctionne: D'abord, nous formaterons la date au format YYYYMMDD ... en tronquant pour ne conserver que les 6 caractères les plus à gauche afin de ne conserver que la partie YYYYMM, puis ajouter '01' comme mois - et le tour est joué! vous avez le premier jour du mois en cours.

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

BTW, les performances sont excellentes à ce sujet!


1

Si vous regardez cela aujourd'hui et que vous utilisez SQL Server 2012 ou une version plus récente, vous disposez de la fonction EOMONTH qui facilite les choses:

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

Vous pouvez modifier GETDATE () avec la variable de date souhaitée.


1

Ici, nous pouvons utiliser la requête ci-dessous pour la première date du mois et la dernière date du mois.

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

1

Si vous utilisez SQL Server 2012 ou supérieur;

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

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

Le -2 vous donnera le premier jour du mois dernier. c'est-à-dire que getdate () est le 15/10/18. Vos résultats seraient le 9/1/18. Changez à -1 et vos résultats seraient le 01/10/18. 0 serait le début du mois prochain, 01/11/2018 .. etc etc.

ou

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

1

Essayez d'exécuter la requête suivante:

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


0

sélectionnez CONVERTIR (date, DATEADD (jj, - (DATEPART (jj, getdate ()) - 1), getdate ()), 120)

Cette fonction vous fournira une partie de la date de début du mois


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

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

Si vous ne voulez pas l'heure, convertissez-la en DATE ou si vous voulez faire passer l'heure à 0:00:00, convertissez-la en DATE puis revenez en DATETIME.

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

Remplacez GETDATE () par la date souhaitée


0

Je recommande personnellement le sql ci-dessous car lorsque j'essaie d'utiliser la fonction date dans la clause condition, cela ralentit beaucoup ma vitesse de requête.

de toute façon, n'hésitez pas à essayer cela.

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

0

Pas pour rivaliser avec aucun des grands esprits ici, mais une simple suggestion légèrement différente de la réponse acceptée ci-dessus.

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

0

J'aime utiliser FORMAT, vous pouvez même spécifier une heure

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

0

Dans Sql Server 2012,

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

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

0

Cette requête devrait très bien fonctionner sur MySQL:

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

0

Pour tous ceux qui recherchent toujours une réponse, cela fonctionne comme un charme et supprime tous les fichiers de données. L'horodatage est facultatif, au cas où il aurait besoin d'être spécifié, mais il fonctionne également sans.

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

0

Obtenez la première date et la dernière date dans la date que nous transmettons comme paramètre dans 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

Voici comment vous le feriez dans MySQL:

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

4
Veuillez spécifier que ce n'est pas une réponse SQL Server mais fonctionne uniquement sur MySQL.
kuklei

Pour SQL Server, vous pouvez utiliserSELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER

N'encouragez pas les gens à formater les dates en chaînes juste pour faire quelque chose qui peut et devrait être fait numériquement. C'est comme dire "vous pouvez arrondir un nombre à la centaine près en le formatant en une chaîne, en sous-chaîne tous sauf les deux derniers chiffres, et en concaténant sur un" 00 ""
Caius Jard
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.