Bagaimana saya bisa memilih hari pertama dalam sebulan di SQL?


308

Saya hanya perlu memilih hari pertama bulan dari variabel datetime yang diberikan.

Saya tahu ini cukup mudah dilakukan dengan menggunakan kode seperti ini:

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

Tapi ini tidak terlalu elegan, dan mungkin juga tidak terlalu cepat.

Apakah ada cara yang lebih baik untuk melakukan ini? Saya menggunakan SQL Server 2008.

Jawaban:


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


63
Perlu dicatat bug yang disebutkan oleh Martin Smith dapat "hanya" mempengaruhi kinerja, bukan kebenaran.
Olson.dev


34
Dalam kasus ada yang bertanya-tanya SELECT EOMONTH(@mydate) AS EndOfMonthakan memberikan hari terakhir bulan.
hallizh

3
Bagaimana saya bisa menentukan apakah bug estimasi kardinalitas yang dicatat akan memengaruhi saya? Itu ditandai sebagai diperbaiki pada tahun 2010. Apakah itu berarti bahwa hanya SQL Server 2012 dan yang lebih baru yang aman, atau mungkin server 2008 mungkin telah ditambal?
Jon

134

Selain semua jawaban di atas, cara berdasarkan pada fungsi yang diperkenalkan di sql 2012

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


14

Pengecoran string (yaitu "5/1/2009") ke datetime tentu lebih mudah dibaca tetapi kami menemukan kode beberapa waktu lalu yang akan mengembalikan yang pertama bulan ...

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

10

Pertanyaan Sederhana:

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

6

Mungkin cukup cepat. Mengapa tidak membuatnya sebagai fungsi 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

Ini juga berfungsi:

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

3

Silakan gunakan ini

  1. Untuk Server 2012

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

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

3

Hari pertama dan terakhir bulan ini:

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

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

Solusi yang benar-benar sederhana dan elegan tetapi perlu diingat bahwa ini juga mengembalikan bagian waktu dari tanggal jika ditentukan dalam variabel.
kuklei

Saya tidak bisa melakukan ini. Selain penutupan braket tambahan, saya mendapatkan error ini: Operand type clash: date is incompatible with int. Saya kira itu karena Anda mencoba menggunakan -operator berkencan?
Sam

Saya tidak tahu seberapa bagus kinerjanya dalam hal kinerja, tetapi tentu berhasil.
salcoin

@ Sam, Anda mengalami bentrokan karena aritmatika sederhana (+, -) berfungsi pada waktu data, bukan pada tanggal.
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

Tapi OP sedang mencari hari pertama bulan ini. Untuk hari terakhir, Anda bisa menggunakan EOMONTH () - sudah seperti ini sejak 2012.
deutschZuid


1

Googler masa depan, di MySQL, coba ini:

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

3
Ini sql-serverpertanyaan, date_subdan intervalmemang mysql.
OGHaza

Bagus, pokoknya, saya mengedit respons. Saya pikir ini masih relevan untuk utas.
Ariel T

1

Saya menggunakan GETDATE () sebagai tanggal untuk bekerja, Anda dapat menggantinya dengan tanggal yang Anda butuhkan.
Begini caranya: Pertama kita memformat tanggal di YYYYMMDD ... format memotong untuk menjaga hanya 6 karakter paling kiri untuk menjaga hanya bagian YYYYMM, dan kemudian menambahkan '01' sebagai bulan - dan voila! Anda memiliki hari pertama bulan ini.

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

BTW, kinerjanya luar biasa!


1

Jika Anda melihat ini hari ini, dan menggunakan SQL server 2012 atau yang lebih baru, Anda memiliki fungsi EOMONTH yang membuat segalanya lebih mudah:

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

Anda dapat mengubah GETDATE () dengan variabel tanggal apa pun yang Anda inginkan.


1

Di sini kita dapat menggunakan kueri di bawah ini untuk tanggal pertama bulan itu dan tanggal terakhir bulan itu.

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

1

Jika menggunakan SQL Server 2012 atau lebih tinggi;

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

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

-2 akan memberi Anda hari pertama bulan lalu. yaitu, getdate () adalah 10/15/18. Hasil Anda akan 9/1/18. Ubah ke -1 dan hasil Anda adalah 10/1/18. 0 akan menjadi awal bulan depan, 11/1/2018 .. dll.

atau

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

1

Coba jalankan kueri berikut:

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


0

pilih CONVERT (tanggal, DATEADD (dd, - (DATEPART (dd, getdate ()) - 1), getdate ()), 120)

Fungsi ini akan memberi Anda tanggal bagian dari tanggal mulai bulan itu


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

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

Jika Anda tidak ingin waktu, maka konversikan ke DATE atau jika ingin membuat waktu ke 0:00:00, Konversikan ke DATE dan kemudian kembali ke DATETIME.

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

Ubah GETDATE () ke tanggal yang Anda inginkan


0

Saya pribadi merekomendasikan bahwa sql di bawah ini karena ketika saya mencoba menggunakan fungsi tanggal dalam klausa kondisi, itu memperlambat kecepatan permintaan saya sangat banyak.

toh merasa bebas untuk mencoba ini.

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

0

Bukan untuk bersaing dengan salah satu pemikir hebat di sini, tetapi saran sederhana sedikit berbeda dengan jawaban yang diterima di atas.

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

0

Saya suka menggunakan FORMAT, Anda bahkan dapat menentukan waktu

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

0

Di Sql Server 2012,

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

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


0

Bagi siapa pun yang masih mencari jawaban, ini berfungsi seperti pesona dan menghilangkan tanggal. Stempel waktu bersifat opsional, seandainya perlu ditentukan, tetapi berfungsi juga.

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

0

Dapatkan Tanggal Pertama dan Tanggal Terakhir di Tanggal yang kami berikan sebagai parameter dalam 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

Begini cara Anda melakukannya di MySQL:

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

4
Silakan tentukan bahwa ini bukan jawaban sql-server tetapi hanya berfungsi pada MySQL.
kuklei

Untuk SQL Server, Anda dapat menggunakanSELECT FORMAT(GETDATE(), 'yyyy-MM-01')
NASSER

Jangan mendorong orang untuk memformat tanggal menjadi string hanya untuk melakukan sesuatu yang dapat dan harus dilakukan secara numerik. Ini seperti mengatakan "Anda dapat membulatkan angka ke angka 100 terdekat dengan memformatnya menjadi string, mengelompokkan semua kecuali dua digit terakhir dari angka itu, dan menyatukannya dengan angka '00'"
Caius Jard
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.