it-swarm-tr.com

SQL sunucusunda bir tarih döşeme

SQL Server'da, bir DATETIME’yi ikinci/dakika/saat/gün/yıla nasıl "döşeyebilirim"?

Diyelim ki 2008-09-17 12: 56: 53.430 tarihim var, o zaman döşeme çıktısı şöyle olmalıdır:

  • Yıl: 2008-01-01 00: 00: 00.000
  • Ay: 2008-09-01 00: 00: 00.000
  • Gün: 2008-09-17 00: 00: 00.000
  • Saat: 2008-09-17 12: 00: 00.000
  • Dakika: 2008-09-17 12: 56: 00.000
  • İkincisi: 2008-09-17 12: 56: 53.000
65
Portman

Anahtar, DATEADD ve DATEDIFF 'yi uygun SQL zaman aralığı sayımı ile birlikte kullanmaktır.

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

Saniyenin altına döşeme yaparken, 0 kullanırsanız, genellikle aritmetik bir taşma alacağınızı unutmayın. Bu nedenle, döşemeye çalıştığınız tarihten daha düşük olduğu bilinen bir değer seçin.

94
Portman

SQL Server'da işte bunun için küçük bir numara:

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

DateTime öğesini, tam sayı bölümü olarak Tarihi ve geçen bir günün kesri olarak Saati temsil eden bir kayan noktaya yayın yaptınız. Ondalık bölümü kesin, sonra onu DateTime'a geri çevirin ve o günün başında gece yarısı var.

Bu muhtemelen tüm DATEADD ve DATEDIFF ürünlerinden daha verimlidir. Yazması kesinlikle daha kolay.

28
Chris Wuestefeld

Convert/Cast çözümünü genişleterek, Microsoft SQL Server 2008'de aşağıdakileri yapabilirsiniz:

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

Sadece getdate() işlevini, bir tarih olan herhangi bir sütunla değiştirin.

Bu dönüşüme dahil olan hiçbir karakter yok.

Bu, geçici sorgular veya güncellemeler için uygundur, ancak anahtar birleşmeleri veya yoğun olarak kullanılan işlemler için, işlem içindeki dönüşümü işlemek veya tabloları uygun anahtarlara ve verilere sahip olacak şekilde yeniden tanımlamak daha iyi olabilir.

2005 yılında, daha katı olanı kullanabilirsiniz: cast(floor(cast(getdate() as float)) as datetime)

Bunun dize dönüşümünü de kullandığını sanmıyorum, ancak koltuk tahminlerine göre gerçek verimliliği karşılaştırmaktan söz edemiyorum.

11
Moe Cazzell

Yıllar boyunca döşeme döşeme tarihlerinde referans olarak @ Portman's answer referansını kullandım ve çalışmasını faydalı bulabileceğiniz bir işleve taşıdım.

Performansı hakkında hiçbir iddiada bulunmam ve sadece kullanıcı için bir araç olarak sunarım.

Soruyorum, bu cevabı yükseltmeye karar verirseniz, lütfen kodumun bir türevi olduğundan @ Portman'ın cevabı kodunu da kaldırın.

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

Kullanım:

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

CONVERT () işlevi, hangi stili kullandığınıza bağlı olarak da yapabilir.

2
Joel Coehoorn

Ne yazık ki Oracle değil, ya da trunc () veya to_char () kullanabilirsiniz.

Ancak SQL Server ile benzer sorunlar yaşadım ve CONVERT () ve DateDiff () yöntemlerini kullandım, here

1
typicalrunt

Bu kedinin ciltlenmesinin çeşitli yolları vardır =)

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

DateAdiff ile birlikte DateAdd birçok farklı görev yapmak için yardımcı olabilir. Örneğin, herhangi bir ayın son gününü, önceki veya sonraki ayın son gününü bulabilirsiniz. 

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

Kaynak

0
pinaldave