it-swarm-id.com

Lantai tanggal di server SQL

Di SQL Server, bagaimana cara "mengukur" DATETIME hingga detik/menit/jam/hari/tahun?

Katakanlah saya memiliki tanggal 2008-09-17 12: 56: 53.430 , maka output dari lantai harus:

  • Tahun: 2008-01-01 00: 00: 00.000
  • Bulan: 2008-09-01 00: 00: 00.000
  • Hari: 2008-09-17 00: 00: 00.000
  • Jam: 2008-09-17 12: 00: 00.000
  • Menit: 2008-09-17 12: 56: 00.000
  • Kedua: 2008-09-17 12: 56: 53.000
65
Portman

Kuncinya adalah menggunakan DATEADD dan DATEDIFF bersama dengan enumerasi SQL rentang waktu yang sesuai.

declare @datetime datetime;
set @datetime = getdate();
select @datetime;
select dateadd(year,datediff(year,0,@datetime),0);
select dateadd(month,datediff(month,0,@datetime),0);
select dateadd(day,datediff(day,0,@datetime),0);
select dateadd(hour,datediff(hour,0,@datetime),0);
select dateadd(minute,datediff(minute,0,@datetime),0);
select dateadd(second,datediff(second,'2000-01-01',@datetime),'2000-01-01');
select dateadd(week,datediff(week,0,@datetime),-1); --Beginning of week is Sunday
select dateadd(week,datediff(week,0,@datetime),0); --Beginning of week is Monday

Perhatikan bahwa ketika Anda melakukan flooring dengan yang kedua, Anda akan sering mendapatkan aritmatika overflow jika Anda menggunakan 0. Jadi, pilih nilai yang diketahui yang dijamin lebih rendah daripada waktu yang Anda coba letakkan.

94
Portman

Di SQL Server, inilah sedikit trik untuk melakukannya:

SELECT CAST(FLOOR(CAST(CURRENT_TIMESTAMP AS float)) AS DATETIME)

Anda melemparkan DateTime ke float, yang mewakili Date sebagai bagian integer dan Waktu sebagai bagian dari hari yang berlalu. Memotong bagian desimal itu, lalu melemparkannya kembali ke DateTime, dan Anda mendapatkan tengah malam di awal hari itu.

Ini mungkin lebih efisien daripada semua hal DATEADD dan DATEIFF. Ini tentu cara yang lebih mudah untuk mengetik.

28
Chris Wuestefeld

Memperluas pada solusi Convert/Cast, di Microsoft SQL Server 2008 Anda dapat melakukan hal berikut:

cast(cast(getdate() as date) as datetime)

Cukup ganti getdate() dengan kolom apa pun yang merupakan datetime.

Tidak ada string yang terlibat dalam konversi ini.

Ini boleh untuk pertanyaan atau pembaruan ad-hoc, tetapi untuk penggabungan kunci atau pemrosesan yang sering digunakan mungkin lebih baik menangani konversi dalam pemrosesan atau mendefinisikan ulang tabel untuk memiliki kunci dan data yang sesuai.

Pada tahun 2005, Anda dapat menggunakan lantai messier: cast(floor(cast(getdate() as float)) as datetime)

Saya tidak berpikir yang menggunakan konversi string juga, tetapi saya tidak dapat berbicara untuk membandingkan efisiensi aktual dibandingkan perkiraan kursi.

11
Moe Cazzell

Saya telah menggunakan @ Portman jawaban berkali-kali selama bertahun-tahun sebagai referensi ketika lantai tanggal dan telah memindahkan fungsinya menjadi fungsi yang mungkin berguna bagi Anda.

Saya tidak mengklaim kinerjanya dan hanya menyediakannya sebagai alat bagi pengguna.

Saya meminta itu, jika Anda memutuskan untuk menaikkan nilai jawaban ini, harap juga upvote @ Portman menjawab , karena kode saya merupakan turunan dari jawabannya.

IF OBJECT_ID('fn_FloorDate') IS NOT NULL DROP FUNCTION fn_FloorDate
SET ANSI_NULLS OFF
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE FUNCTION [dbo].[fn_FloorDate] (
  @Date DATETIME = NULL,
  @DatePart VARCHAR(6) = 'day'
)
RETURNS DATETIME
AS
BEGIN
  IF (@Date IS NULL)
    SET @Date = GETDATE();

  RETURN
  CASE
    WHEN LOWER(@DatePart) = 'year' THEN DATEADD(YEAR, DATEDIFF(YEAR, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'month' THEN DATEADD(MONTH, DATEDIFF(MONTH, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'day' THEN DATEADD(DAY, DATEDIFF(DAY, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'hour' THEN DATEADD(HOUR, DATEDIFF(HOUR, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'minute' THEN DATEADD(MINUTE, DATEDIFF(MINUTE, 0, @Date), 0)
    WHEN LOWER(@DatePart) = 'second' THEN DATEADD(SECOND, DATEDIFF(SECOND, '2000-01-01', @Date), '2000-01-01')
    ELSE DATEADD(DAY, DATEDIFF(DAY, 0, @Date), 0)
  END;
END

Penggunaan:

DECLARE @date DATETIME;
SET @date = '2008-09-17 12:56:53.430';

SELECT
  @date AS [Now],--2008-09-17 12:56:53.430
  dbo.fn_FloorDate(@date, 'year') AS [Year],--2008-01-01 00:00:00.000
  dbo.fn_FloorDate(default, default) AS [NoParams],--2013-11-05 00:00:00.000
  dbo.fn_FloorDate(@date, default) AS [ShouldBeDay],--2008-09-17 00:00:00.000
  dbo.fn_FloorDate(@date, 'month') AS [Month],--2008-09-01 00:00:00.000
  dbo.fn_FloorDate(@date, 'day') AS [Day],--2008-09-17 00:00:00.000
  dbo.fn_FloorDate(@date, 'hour') AS [Hour],--2008-09-17 12:00:00.000
  dbo.fn_FloorDate(@date, 'minute') AS [Minute],--2008-09-17 12:56:00.000
  dbo.fn_FloorDate(@date, 'second') AS [Second];--2008-09-17 12:56:53.000
6
Dan Atkinson

Fungsi CONVERT () dapat melakukan ini juga, tergantung pada gaya apa yang Anda gunakan.

2
Joel Coehoorn

Sayang sekali itu bukan Oracle, atau Anda bisa menggunakan trunc () atau to_char ().

Tapi saya punya masalah serupa dengan SQL Server dan menggunakan metode CONVERT () dan DateDiff (), seperti yang dirujuk di sini

1
typicalrunt

Ada beberapa cara untuk menguliti kucing ini =)

select convert(datetime,convert(varchar,CURRENT_TIMESTAMP,101))
0
Sean

DateAdd bersama DateDiff dapat membantu melakukan banyak tugas berbeda. Misalnya, Anda dapat menemukan hari terakhir bulan apa pun dan juga dapat menemukan hari terakhir bulan sebelumnya atau berikutnya. 

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

Sumber

0
pinaldave