適用於: SQL Server 2022 (16.x)
Azure SQL Database Azure
SQL Managed Instance
Azure SQL Edge
SQL database in Microsoft Fabric
此函數會從 origin 參數定義的時間戳記傳回與每個日期時間儲存貯體開始相對應的日期時間值,如果未指定 origin 參數,則傳回預設 origin 值 1900-01-01 00:00:00.000 。
如需所有 Transact-SQL 日期和時間數據類型和函式的概觀,請參閱 日期和時間 數據類型和函式。
語法
DATE_BUCKET (datepart , number , date [ , origin ] )
引數
datepart
與 number 參數搭配使用的日期部分,例如年、月、日、分鐘、秒。
DATE_BUCKET 不會接受 datepart 引數的使用者定義變數對等項目。
| datepart | 縮寫 |
|---|---|
| day | dd、 d |
| week | 週, 週 |
| month | 毫米、 米 |
| quarter | qq,q |
| year | yy,yyyy |
| hour | hh |
| minute | 米, 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 參數對應的最新日期或時間值。 例如,在下列表達式中,會傳回 的DATE_BUCKET輸出值,2020-04-13 00:00:00.0000000因為輸出是根據預設源時間1900-01-01 00:00:00.000的一周值區計算。 值 2020-04-13 00:00:00.0000000 是在原始值 1900-01-01 00:00:00.000 後的 6,276 週。
DECLARE @date AS 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 是在原始日期後的 6,276 週,而 6,276 可由 2、3、4 和 6 整除。
DECLARE @date AS 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.0006,275 週。
DECLARE @date AS 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 AS DATETIME2 = '2020-06-15 21:22:11';
DECLARE @origin AS DATETIME2 = '2019-01-01 00:00:00';
SELECT DATE_BUCKET(WEEK, 5, @date, @origin);
datepart 引數
dayofyear、day 和 weekday 都會傳回相同的值。 每個 datepart 及其縮寫都會傳回相同的值。
數字引數
number 引數不得超過正數 int 值的範圍。 在下列陳述式中,number 引數超過 int 的範圍 (超過 1)。 下列陳述式會傳回錯誤訊息: Msg 8115, Level 16, State 2, Line 2. Arithmetic overflow error converting expression to data type int.
DECLARE @date AS 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());
起源引數
中原點和日期自變數的數據類型必須相同。 如果使用不同的數據類型,就會產生錯誤。
備註
在下列子句中使用 DATE_BUCKET:
GROUP BYHAVINGORDER BYSELECT <list>WHERE
範例
本文中的程式代碼範例會使用 AdventureWorks2025 或 AdventureWorksDW2025 範例資料庫,您可以從 Microsoft SQL Server 範例和社群專案 首頁下載。
A. 使用值區寬度 1 從原始時間計算 DATE_BUCKET
這些陳述式各自會從原始時間以值區寬度 1 遞增 DATE_BUCKET:
DECLARE @date AS 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 參數的引數
這些範例會使用不同的運算式類型,作為 number 和 date 參數的引數。
這些範例是使用 AdventureWorksDW2025 資料庫所建置的。
將使用者自訂變數指定為 number 和 date
此範例會將使用者定義變數指定為 number 和 date 的引數:
DECLARE @days AS INT = 365,
@datetime AS DATETIME2 = '2000-01-01 01:01:01.1110000';
SELECT DATE_BUCKET(DAY, @days, @datetime);
結果集如下所示。
1999-12-08 00:00:00.0000000
將資料行指定為 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 AS 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
這個範例會針對 SYSDATETIME 指定 。 傳回的精確值取決於陳述式執行的日期和時間:
SELECT DATE_BUCKET(WEEK, 10, SYSDATETIME());
結果集如下所示。
2020-03-02 00:00:00.0000000
將純量子查詢和純量函數指定為 number 和 date
此範例會使用純量子查詢 MAX(OrderDate),作為 number 和 date 的引數。
(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) 作為 數字 和 日期的引數。
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 AS DATETIME2 = '2020-06-15 21:22:11';
DECLARE @origin AS DATETIME2 = '2019-01-01 00:00:00';
SELECT DATE_BUCKET(HOUR, 2, @date, @origin);