DATETRUNC (Transact-SQL)

Gäller för: SQL Server 2022 (16.x) Azure SQL DatabaseAzure SQL Managed InstanceSQL analytics endpoint in Microsoft FabricWarehouse in Microsoft Fabric SQLdatabase in Microsoft Fabric

Funktionen DATETRUNC returnerar ett indatadatum som trunkerats till en specificerad datepart.

Anmärkning

DATETRUNC introducerades i SQL Server 2022 (16.x).

Syntax

DATETRUNC ( datepart , date )

Arguments

datepart

Specificerar precisionen för trunkering. Denna tabell listar alla giltiga datumdelsvärden för DATETRUNC, givet att det också är en giltig del av indatadatumstypen.

datepart Abbreviations Kortningsnoteringar
year yy, yyyy
quarter qq, q
month mm, m
dayofyear dy, y dayofyear trunkeras på samma sätt som day
day dd, d day trunkeras på samma sätt som dayofyear
week wk, ww Korta av till veckans första dag. I T-SQL definieras veckans första dag av T-SQL-inställningen @@DATEFIRST . För en miljö på amerikansk engelska är @@DATEFIRST standardinställningen 7 (söndag).
iso_week isowk, isoww Korta av till första dagen av en ISO-vecka. Veckodagen i ISO8601 kalendersystem är måndag.
hour hh
minute mi, n
second ss, s
millisecond ms
microsecond mcs

Anmärkning

Vardags-, tidszonsförskjutnings- och nanosekunders T-SQL-datumdelar stöds inte för DATETRUNC.

date

Accepterar alla uttryck, kolumner eller användardefinierade variabler som kan lösas till vilken giltig T-SQL-datum eller tidtyp som helst. Giltiga typer är:

  • smalldatetime
  • datetime
  • date
  • time
  • datetime2
  • datetimeoffset

Blanda inte ihop datumparametern med datumdatatypen .

DATETRUNCaccepterar också en strängbokstav (av valfri strängtyp) som kan lösas till en datetime2(7).

Returtyper

Den returnerade datatypen för DATETRUNC är dynamisk. DATETRUNC returnerar ett trunkerat datum av samma datatyp (och, om tillämpligt, samma fraktionella tidsskala) som inmatningsdatumet. Till exempel, om DATETRUNC den fick ett datumtimeoffset(3)-inmatningsdatum, skulle det returnera ett datumtimeoffset(3). Om den fick en strängbokstav som kunde upplösas till en datetime2(7),DATETRUNC skulle det returnera en datetime2(7).

Fraktionell tidsskalans precision

Millisekunder har en fraktionell tidsskala på 3 (.123), mikrosekunder har en fraktionell tidsskala på 6 (.123456), och nanosekunder har en fraktionell tidsskala på 9 (.123456789). Datatyperna tid, datetime2 och datetimeoffset-typerna tillåter en maximal fraktionell tidsskala på 7 (.1234567). Därför måste den bråkdelade tidsskalan vara minst 3 för att avkorta till datumdelenmillisecond. På samma sätt, för att trunkera till microseconddateparten, måste den bråkdelade tidsskalan vara minst 6. DATETRUNC stöder inte nanoseconddatumdelen eftersom ingen T-SQL-datumtyp stöder en bråkdel av tidsskalan 9.

Examples

A. Använd olika datumdelsalternativ

Följande exempel illustrerar användningen av olika datumdelsalternativ :

DECLARE @d datetime2 = '2021-12-08 11:30:15.1234567';
SELECT 'Year', DATETRUNC(year, @d);
SELECT 'Quarter', DATETRUNC(quarter, @d);
SELECT 'Month', DATETRUNC(month, @d);
SELECT 'Week', DATETRUNC(week, @d); -- Using the default DATEFIRST setting value of 7 (U.S. English)
SELECT 'Iso_week', DATETRUNC(iso_week, @d);
SELECT 'DayOfYear', DATETRUNC(dayofyear, @d);
SELECT 'Day', DATETRUNC(day, @d);
SELECT 'Hour', DATETRUNC(hour, @d);
SELECT 'Minute', DATETRUNC(minute, @d);
SELECT 'Second', DATETRUNC(second, @d);
SELECT 'Millisecond', DATETRUNC(millisecond, @d);
SELECT 'Microsecond', DATETRUNC(microsecond, @d);

Här är resultatet.

Year        2021-01-01 00:00:00.0000000
Quarter     2021-10-01 00:00:00.0000000
Month       2021-12-01 00:00:00.0000000
Week        2021-12-05 00:00:00.0000000
Iso_week    2021-12-06 00:00:00.0000000
DayOfYear   2021-12-08 00:00:00.0000000
Day         2021-12-08 00:00:00.0000000
Hour        2021-12-08 11:00:00.0000000
Minute      2021-12-08 11:30:00.0000000
Second      2021-12-08 11:30:15.0000000
Millisecond 2021-12-08 11:30:15.1230000
Microsecond 2021-12-08 11:30:15.1234560

B. @@DATEFIRST miljö

Följande exempel illustrerar användningen av miljön @@DATEFIRST med weekdatumdelen:

DECLARE @d datetime2 = '2021-11-11 11:11:11.1234567';

SELECT 'Week-7', DATETRUNC(week, @d); -- Uses the default DATEFIRST setting value of 7 (U.S. English)

SET DATEFIRST 6;
SELECT 'Week-6', DATETRUNC(week, @d);

SET DATEFIRST 3;
SELECT 'Week-3', DATETRUNC(week, @d);

Här är resultatet.

Week-7  2021-11-07 00:00:00.0000000
Week-6  2021-11-06 00:00:00.0000000
Week-3  2021-11-10 00:00:00.0000000

C. Datumbokstaver

Följande exempel illustrerar användningen av datumparameterliteraler:

SELECT DATETRUNC(month, '1998-03-04');

SELECT DATETRUNC(millisecond, '1998-03-04 10:10:05.1234567');

DECLARE @d1 char(200) = '1998-03-04';
SELECT DATETRUNC(millisecond, @d1);

DECLARE @d2 nvarchar(max) = '1998-03-04 10:10:05';
SELECT DATETRUNC(minute, @d2);

Här är resultatet. Alla resultat är av typen datetime2(7).

1998-03-01 00:00:00.0000000
1998-03-04 10:10:05.1230000
1998-03-04 00:00:00.0000000
1998-03-04 10:10:00.0000000

D. Variabler och datumparametern

Följande exempel illustrerar användningen av datumparametern :

DECLARE @d datetime2 = '1998-12-11 02:03:04.1234567';
SELECT DATETRUNC(day, @d);

Här är resultatet.

1998-12-11 00:00:00.0000000

E. Kolumner och datumparametern

Kolumnen TransactionDate i Sales.CustomerTransactions tabellen fungerar som ett exempel på ett kolumnargument för datumparametern :

USE WideWorldImporters;
GO

SELECT CustomerTransactionID,
    DATETRUNC(month, TransactionDate) AS MonthTransactionOccurred,
    InvoiceID,
    CustomerID,
    TransactionAmount,
    SUM(TransactionAmount) OVER (
        PARTITION BY CustomerID ORDER BY TransactionDate,
            CustomerTransactionID ROWS UNBOUNDED PRECEDING
        ) AS RunningTotal,
    TransactionDate AS ActualTransactionDate
FROM [WideWorldImporters].[Sales].[CustomerTransactions]
WHERE InvoiceID IS NOT NULL
    AND DATETRUNC(month, TransactionDate) >= '2015-12-01';

F. Uttryck och datumparametern

Datumparametern accepterar alla uttryck som kan lösas till en T-SQL-datumtyp eller vilken strängbokstav som helst som kan lösas till en datetime2(7). Kolumnen TransactionDate i Sales.CustomerTransactions tabellen fungerar som ett konstlat argument för att exemplifiera användningen av ett uttryck för datumparametern :

SELECT DATETRUNC(m, SYSDATETIME());

SELECT DATETRUNC(yyyy, CONVERT(date, '2021-12-1'));

USE WideWorldImporters;
GO
SELECT DATETRUNC(month, DATEADD(month, 4, TransactionDate))
FROM Sales.CustomerTransactions;
GO

G. Förkorta ett datum till en datepart som representerar dess maximala precision

Om dateparten har samma enhetsmaximala precision som indatatypen, skulle det inte ha någon effekt att trunkera indatadatumet till detta datepart .

Exempel 1

DECLARE @d datetime = '2015-04-29 05:06:07.123';
SELECT 'Input', @d;
SELECT 'Truncated', DATETRUNC(millisecond, @d);

Här är resultatet. Indata datetime och trunkerad datumparameter är samma.

Input     2015-04-29 05:06:07.123
Truncated 2015-04-29 05:06:07.123

Exempel 2

DECLARE @d date = '2050-04-04';
SELECT 'Input', @d;
SELECT 'Truncated', DATETRUNC(day, @d);

Här är resultatet. Indata datetime och trunkerad datumparameter är samma.

Input     2050-04-04
Truncated 2050-04-04

Exempel 3: precisionen small datetime

smalldatetime är bara exakt upp till närmaste minut, även om det finns ett fält för sekunder. Därför skulle det inte ha någon effekt att trunkera till närmaste minut eller närmaste sekund.

DECLARE @d smalldatetime = '2009-09-11 12:42:12'
SELECT 'Input', @d;
SELECT 'Truncated to minute', DATETRUNC(minute, @d)
SELECT 'Truncated to second', DATETRUNC(second, @d);

Här är resultatet. Det inmatade smalldatetime-värdet är detsamma som båda de trunkerade värdena:

Input                2009-09-11 12:42:00
Truncated to minute  2009-09-11 12:42:00
Truncated to second  2009-09-11 12:42:00

Exempel 4: datumtidsprecision

Datumtid är bara exakt upp till 3,33 millisekunder. Därför kan en förkortning av en datetime till en millisekund ge resultat som skiljer sig från vad användaren förväntar sig. Detta trunkerade värde är dock samma som det internt lagrade datetime-värdet .

DECLARE @d datetime = '2020-02-02 02:02:02.002';
SELECT 'Input', @d;
SELECT 'Truncated', DATETRUNC(millisecond, @d);

Här är resultatet. Det trunkerade datumet är detsamma som det lagrade datumet. Detta kan skilja sig från vad du förväntar dig baserat på påståendet DECLARE .

Input     2020-02-02 02:02:02.003
Truncated 2020-02-02 02:02:02.003

Anmärkningar

Ett fel uppstår om datumtrunkeringen försöker backa till ett datum före det minsta datum som stöds av den datatypen. Detta fel uppstår endast när jag använder weekdateparten. Det kan inte ske när man använder iso_weekdatumdelen, eftersom alla T-SQL-datumtyper av en slump använder en måndag som sina minsta datum. Här är ett exempel med motsvarande felmeddelande om resultat:

DECLARE @d date= '0001-01-01 00:00:00';
SELECT DATETRUNC(week, @d);
Msg 9837, Level 16, State 3, Line 84
An invalid date value was encountered: The date value is less than the minimum date value allowed for the data type.

Ett DATEPART fel kastas om DATETRUNC funktionen, eller datatypen för inmatningsdatum, inte stöder dateparten som används. Detta fel kan uppstå när:

  1. En datepart som inte stöds av DATETRUNC används (nämligen, weekday, tzoffset, eller nanosecond)

  2. En tidsrelateraddatepart används med datumdatatypen eller en daterelateraddatepart med tidsdatatypen . Här är ett exempel med motsvarande felmeddelande om resultat:

    DECLARE @d time = '12:12:12.1234567';
    SELECT DATETRUNC(year, @d);
    
    Msg 9810, Level 16, State 10, Line 78
    The datepart year is not supported by date function datetrunc for data type time.
    
  3. Datedelen kräver en högre precisionsgrad i fraktionell tidsskala än vad datatypen tillåter. För mer information, se Fractional time scale precision. Här är ett exempel med motsvarande felmeddelande om resultat:

    DECLARE @d datetime2(3) = '2021-12-12 12:12:12.12345';
    SELECT DATETRUNC(microsecond, @d);
    
    Msg 9810, Level 16, State 11, Line 81
    The datepart microsecond is not supported by date function datetrunc for data type datetime2.