it-swarm-eu.dev

Geben Sie ein Datum in SQL Server ab

Wie kann ein DATETIME in SQL Server auf die Sekunde/Minute/Stunde/Tag/Jahr gesetzt werden?

Nehmen wir an, ich habe ein Datum von 2008-09-17 12: 56: 53.430 , dann sollte die Ausgabe des Bodenbelags sein:

  • Jahr: 2008-01-01 00: 00: 00.000
  • Monat: 2008-09-01 00: 00: 00.000
  • Tag: 2008-09-17 00: 00: 00.000
  • Stunde: 2008-09-17 12: 00: 00.000
  • Minute: 2008-09-17 12: 56: 00.000
  • Zweitens: 2008-09-17 12: 56: 53.000
65
Portman

Der Schlüssel ist die Verwendung von DATEADD und DATEDIFF zusammen mit der entsprechenden SQL-Zeitbereichsaufzählung.

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

Beachten Sie, dass Sie bei Verwendung von 0 häufig einen arithmetischen Überlauf erhalten, wenn Sie 0 verwenden. Wählen Sie also einen bekannten Wert aus, der garantiert niedriger ist als die Datumszeit, die Sie versuchen, einen Platz zu erreichen.

94
Portman

In SQL Server gibt es hier einen kleinen Trick:

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

Sie setzen die DateTime in einen Float um, der das Datum als ganzzahligen Teil und die Uhrzeit als Bruchteil eines Tages darstellt. Zerhacken Sie den Dezimalanteil und werfen Sie ihn zurück in eine DateTime-Zeit, und Sie haben zu Beginn dieses Tages Mitternacht.

Dies ist wahrscheinlich effizienter als alle DATEADD- und DATEDIFF-Dateien. Es ist sicherlich viel einfacher zu tippen.

28

In Microsoft SQL Server 2008 können Sie die Convert/Cast-Lösung erweitern und Folgendes tun:

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

Ersetzen Sie einfach getdate() durch eine beliebige Spalte, die eine Datumszeit ist.

An dieser Konvertierung sind keine Zeichenfolgen beteiligt.

Dies ist für Ad-hoc-Abfragen oder -Updates in Ordnung, aber für Schlüsselverknüpfungen oder eine häufig verwendete Verarbeitung ist es möglicherweise besser, die Konvertierung innerhalb der Verarbeitung auszuführen oder die Tabellen neu zu definieren, um die entsprechenden Schlüssel und Daten zu erhalten.

Im Jahr 2005 können Sie die unordentlichere Etage verwenden: cast(floor(cast(getdate() as float)) as datetime)

Ich denke nicht, dass dies auch eine String-Konvertierung verwendet, aber ich kann nicht sprechen, die tatsächliche Effizienz mit den Schätzungen der Sessel zu vergleichen.

11
Moe Cazzell

Ich habe @Portmans Antwort im Laufe der Jahre oft als Referenz für Fußbodenbeläge verwendet und ihre Arbeitsweise in eine Funktion überführt, die Sie vielleicht nützlich finden.

Ich mache keinen Anspruch auf die Leistung und stelle sie lediglich als Werkzeug für den Benutzer zur Verfügung.

Ich bitte darum, dass Sie, wenn Sie sich dazu entschließen, diese Antwort zu verbessern, auch @Portmans Antwort verbessern, da mein Code eine Ableitung von seinem ist.

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

Verwendung:

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

Die Funktion CONVERT () kann dies ebenfalls tun, je nachdem, welchen Stil Sie verwenden.

2
Joel Coehoorn

Schade, dass es nicht Oracle ist, oder Sie könnten trunc () oder to_char () verwenden.

Ich hatte jedoch ähnliche Probleme mit SQL Server und verwendete die CONVERT () - und DateDiff () -Methoden, wie auf hier verwiesen.

1
typicalrunt

Es gibt mehrere Möglichkeiten, diese Katze zu enthäuten =)

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

DateAdd kann zusammen mit DateDiff bei vielen verschiedenen Aufgaben helfen. Zum Beispiel können Sie den letzten Tag eines jeden Monats sowie den letzten Tag des vorherigen oder nächsten Monats suchen. 

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

Quelle

0
pinaldave