DATE_BUCKET (Transact-SQL)

重要

Azure SQL Edge 不再支援 ARM64 平臺。

此函式會從參數所 origin 定義的時間戳記,傳回對應至每個 datetime 值區開頭的 datetime 值,如果未指定源參數,則傳回 的預設原點值 1900-01-01 00:00:00.000

如需所有 Transact-SQL 日期和時間資料類型與函式的概觀,請參閱日期和時間資料類型與函式 (Transact-SQL)

Transact-SQL 語法慣例

語法

DATE_BUCKET (datePart , number , date , origin)

引數

datePart

與 'number' 參數搭配使用的日期 部分 ,如下表所示。 DATE_BUCKET不接受 datePart 引數的使用者定義變數對等 專案。

datePart 縮寫
day dd, d
week wk, ww
month mm, m
quarter qq, q
year yy, yyyy
hour hh
minute mi, n
second ss, s
millisecond ms

number

決定 值區寬度與 datePart 引數結合的整數 編號。 這代表從原點時間開始的 datePart 貯體寬度。 這個引數必須是 整數值。

date

可解析成下列其中一個值的運算式:

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

對於 date DATE_BUCKET 如果資料行運算式、運算式或使用者定義變數解析為先前所述的任何資料類型,則接受它們。

origin

可解析成下列其中一個值的選擇性運算式:

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

資料的 資料類型應該符合 date 參數的 資料類型。

DATE_BUCKET 會使用預設原點日期值 1900-01-01 00:00:00.000 ,也就是在 1900 年 1 月 1 日星期一上午 12:00,如果未指定函式的原始 值。

傳回類型

這個方法的傳回值資料類型為動態。 傳回型別取決於提供給 date 的引數。 如果為日期 提供 有效的輸入資料類型, DATE_BUCKET 則傳回相同的資料類型。 DATE_BUCKET如果為 date 參數指定字串常值, 就會引發錯誤。

傳回值

瞭解輸出的來源 DATE_BUCKET

DATE_BUCKET 會傳回最新的日期或時間值,對應至 datePart number 參數。 例如,在下列運算式中,會傳回 的 2020-04-13 00:00:00.0000000 輸出值, DATE_BUCKET 因為輸出是根據預設源時間 1900-01-01 00:00:00.000 的一周值區計算。 值為 2020-04-13 00:00:00.0000000 6276 周的原點值 1900-01-01 00:00:00.000

DECLARE @date DATETIME2 = '2020-04-15 21:22:11';

SELECT DATE_BUCKET(WEEK, 1, @date);

針對下列所有運算式,會傳回 的相同輸出值 2020-04-13 00:00:00.0000000 。 這是因為 2020-04-13 00:00:00.0000000 距離原點日期為 6276 周,而 6276 則以 2、3、4 和 6 來分隔。

DECLARE @date DATETIME2 = '2020-04-15 21:22:11';

SELECT DATE_BUCKET(WEEK, 2, @date);
SELECT DATE_BUCKET(WEEK, 3, @date);
SELECT DATE_BUCKET(WEEK, 4, @date);
SELECT DATE_BUCKET(WEEK, 6, @date);

下列運算式的輸出是 2020-04-06 00:00:00.0000000,這是預設原始時間 1900-01-01 00:00:00.000 後的 6275 週。

DECLARE @date DATETIME2 = '2020-04-15 21:22:11';

SELECT DATE_BUCKET(WEEK, 5, @date);

以下運算式的輸出為 2020-06-09 00:00:00.0000000 ,距離指定的源時間 2019-01-01 00:00:00 為 75 周。

DECLARE @date DATETIME2 = '2020-06-15 21:22:11';
DECLARE @origin DATETIME2 = '2019-01-01 00:00:00';

SELECT DATE_BUCKET(WEEK, 5, @date, @origin);

備註

在下列子句中使用 DATE_BUCKET

  • GROUP BY
  • HAVING
  • ORDER BY
  • SELECT <list>
  • WHERE

datePart 參數

dayofyeardayweekday 都會傳回相同的值。 每個 datePart 及其縮寫都會傳回相同的值。

number 引數

number 引數不得超過正數 int 值的範圍。 在下列陳述式中,number 引數超過 int 的範圍 (超過 1)。 下列語句會傳回下列錯誤訊息: Msg 8115, Level 16, State 2, Line 2. Arithmetic overflow error converting expression to data type int.

DECLARE @date DATETIME2 = '2020-04-30 00:00:00';

SELECT DATE_BUCKET(DAY, 2147483648, @date);

如果數位的負值傳遞至函 DATE_BUCKET 式,則會傳回下列錯誤。

Msg 9834, Level 16, State 1, Line 1
Invalid bucket width value passed to DATE_BUCKET function. Only positive values are allowed.

date 引數

DATE_BUCKET會傳回對應至 date 引數資料類型的 基底值。 在下列範例中,會傳回具有 datetime2 資料類型的輸出值。

SELECT DATE_BUCKET(DAY, 10, SYSUTCDATETIME());

origin 引數

中原點 日期 引數的 資料類型必須相同。 如果使用不同的資料類型,就會產生錯誤。

範例

A. 使用值區寬度 1 從原始時間計算 DATE_BUCKET

每一個語句都會 遞增DATE_BUCKET ,其值區寬度為 1,從原點時間:

DECLARE @date DATETIME2 = '2020-04-30 21:21:21';

SELECT 'Week', DATE_BUCKET(WEEK, 1, @date)
UNION ALL SELECT 'Day', DATE_BUCKET(DAY, 1, @date)
UNION ALL SELECT 'Hour', DATE_BUCKET(HOUR, 1, @date)
UNION ALL SELECT 'Minutes', DATE_BUCKET(MINUTE, 1, @date)
UNION ALL SELECT 'Seconds', DATE_BUCKET(SECOND, 1, @date);

結果集如下所示。

Week    2020-04-27 00:00:00.0000000
Day     2020-04-30 00:00:00.0000000
Hour    2020-04-30 21:00:00.0000000
Minutes 2020-04-30 21:21:00.0000000
Seconds 2020-04-30 21:21:21.0000000

B. 使用運算式當做 number 和 date 參數的引數

這些範例會使用不同的運算式類型,作為 numberdate 參數的引數。 這些範例是使用 AdventureWorksDW2019 Database 所建置。

將使用者自訂變數指定為 number 和 date

此範例會將使用者定義變數指定為 numberdate 的引數:

DECLARE @days INT = 365,
    @datetime DATETIME2 = '2000-01-01 01:01:01.1110000';/* 2000 was a leap year */;

SELECT DATE_BUCKET(DAY, @days, @datetime);

結果集如下所示。

---------------------------
1999-12-08 00:00:00.0000000

(1 row affected)

將資料行指定為 date

在下列範例中,我們會計算依每週日期值區分組的 OrderQuantity 和 UnitPrice 的總和。

SELECT DATE_BUCKET(WEEK, 1, CAST(Shipdate AS DATETIME2)) AS ShippedDateBucket,
    Sum(OrderQuantity) AS SumOrderQuantity,
    Sum(UnitPrice) AS SumUnitPrice
FROM dbo.FactInternetSales FIS
WHERE Shipdate BETWEEN '2011-01-03 00:00:00.000'
        AND '2011-02-28 00:00:00.000'
GROUP BY DATE_BUCKET(week, 1, CAST(Shipdate AS DATETIME2))
ORDER BY ShippedDateBucket;

結果集如下所示。

ShippedDateBucket           SumOrderQuantity SumUnitPrice
--------------------------- ---------------- ---------------------
2011-01-03 00:00:00.0000000 21               65589.7546
2011-01-10 00:00:00.0000000 27               89938.5464
2011-01-17 00:00:00.0000000 31               104404.9064
2011-01-24 00:00:00.0000000 36               118525.6846
2011-01-31 00:00:00.0000000 39               123555.431
2011-02-07 00:00:00.0000000 35               109342.351
2011-02-14 00:00:00.0000000 32               107804.8964
2011-02-21 00:00:00.0000000 37               119456.3428
2011-02-28 00:00:00.0000000 9                28968.6982

將純量系統函數指定為 date

這個範例會針對 date 指定 SYSDATETIME。 傳回的精確值取決於陳述式執行的日期和時間:

SELECT DATE_BUCKET(WEEK, 10, SYSDATETIME());

結果集如下所示。

---------------------------
2020-03-02 00:00:00.0000000

(1 row affected)

將純量子查詢和純量函數指定為 number 和 date

此範例會使用純量子查詢 MAX(OrderDate),作為 numberdate 的引數。 (SELECT top 1 CustomerKey FROM dbo.DimCustomer where GeographyKey > 100) 會作為 number 參數的人工引數,以示範如何從值清單中選取 number 引數。

SELECT DATE_BUCKET(WEEK,
        (
            SELECT TOP 1 CustomerKey
            FROM dbo.DimCustomer
            WHERE GeographyKey > 100
        ),
        (
            SELECT MAX(OrderDate)
            FROM dbo.FactInternetSales
        )
    );

將數值運算式和純量系統函數指定為 number 和 date

此範例使用數值運算式 (10/2)和純量系統函式 (SYSDATETIME) 做為 number 和 date 的引數。

SELECT DATE_BUCKET(WEEK, (10 / 2), SYSDATETIME());

將彙總視窗函式指定為 number

此範例會使用彙總視窗函式,作為 number 的引數。

SELECT DISTINCT DATE_BUCKET(DAY, 30, CAST([shipdate] AS DATETIME2)) AS DateBucket,
    FIRST_VALUE([SalesOrderNumber]) OVER (
        ORDER BY DATE_BUCKET(DAY, 30, CAST([shipdate] AS DATETIME2))
        ) AS FIRST_VALUE_In_Bucket,
    LAST_VALUE([SalesOrderNumber]) OVER (
        ORDER BY DATE_BUCKET(DAY, 30, CAST([shipdate] AS DATETIME2))
        ) AS LAST_VALUE_In_Bucket
FROM [dbo].[FactInternetSales]
WHERE ShipDate BETWEEN '2011-01-03 00:00:00.000'
        AND '2011-02-28 00:00:00.000'
ORDER BY DateBucket;
GO

C. 使用非預設原始值

此範例會使用非預設原始值來產生日期值區。

DECLARE @date DATETIME2 = '2020-06-15 21:22:11';
DECLARE @origin DATETIME2 = '2019-01-01 00:00:00';

SELECT DATE_BUCKET(HOUR, 2, @date, @origin);

另請參閱