it-swarm-eu.dev

Podlahové datum v SQL serveru

V SQL Server, jak mám "podlaha" DATETIME na druhou/minutu/hodinu/den/rok?

Řekněme, že mám datum 2008-09-17 12: 56: 53.430 , pak by měl být výstup podlah:

  • Rok: 2008-01-01 00: 00: 00.000
  • Měsíc: 2008-09-01 00: 00: 00.000
  • Den: 2008-09-17 00: 00: 00.000
  • Hodina: 2008-09-17 12: 00: 00.000
  • Zápis: 2008-09-17 12: 56: 00.000
  • Za druhé: 2008-09-17 12: 56: 53.000
65
Portman

Klíčem je použít DATEADD a DATEDIFF spolu s příslušným výčtem časových úseků SQL.

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

Všimněte si, že při podlahové krytině druhé, budete často dostat aritmetické přetečení, pokud použijete 0. Tak si vyberte známou hodnotu, která je zaručena, že je nižší než datetime se snažíte na podlahu.

94
Portman

V SQL Serveru je to trochu trik:

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

Vložíte DateTime do float, který představuje datum jako celočíselnou část a čas jako zlomek dne, který je předán. Vypněte tuto desetinnou část, pak ji vraťte zpět do DateTime a na začátku toho dne máte půlnoc.

To je pravděpodobně efektivnější než všechny věci DATEADD a DATEDIFF. Je to určitě snazší psát.

28
Chris Wuestefeld

Rozbalením řešení Convert/Cast v Microsoft SQL Server 2008 můžete provést následující:

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

Stačí nahradit getdate() libovolným sloupcem, který je datetime.

V této konverzi nejsou zahrnuty žádné řetězce.

To je v pořádku pro ad-hoc dotazy nebo aktualizace, ale pro klíčové spojení nebo silně používané zpracování může být lepší zpracovat konverzi v rámci zpracování nebo předefinovat tabulky tak, aby měly odpovídající klíče a data.

V roce 2005 můžete použít podlahy messier: cast(floor(cast(getdate() as float)) as datetime)

Nemyslím si, že by se jednalo o konverzi řetězců, ale nemůžu mluvit srovnáním skutečných efektivností s odhady křesel.

11
Moe Cazzell

Použil jsem @ Portmanova odpověď mnohokrát v průběhu let jako reference při datování podlah a přesunul jsem jeho práci do funkce, kterou můžete považovat za užitečnou.

Neodpovídám za jeho výkon a pouze jej poskytuji jako nástroj pro uživatele.

Ptám se, že pokud se rozhodnete tuto odpověď potvrdit, prosím, také upvote @ Portmanova odpověď , protože můj kód je derivátem jeho.

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

Použití:

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

Funkce CONVERT () to může provést také v závislosti na tom, jaký styl používáte.

2
Joel Coehoorn

Škoda, že to není Oracle, jinak byste mohli použít trunc () nebo to_char ().

Ale měl jsem podobné problémy s SQL Serverem a používal metody CONVERT () a DateDiff (), jak je uvedeno zde

1
typicalrunt

Existuje několik způsobů, jak tuto kočku skrýt =)

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

DateAdd spolu s DateDiff může pomoci dělat mnoho různých úkolů. Například, můžete najít poslední den v každém měsíci, stejně jako najít poslední den předchozího nebo příštího měsíce. 

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

Zdroj

0
pinaldave