DATE_BUCKET (Transact-SQL)
重要
Azure SQL Edge 將於 2025 年 9 月 30 日淘汰。 如需詳細資訊和移轉選項,請參閱 淘汰通知。
注意
Azure SQL Edge 不再支援 ARM64 平台。
此函式會從參數所 origin
定義的時間戳,傳回對應至每個 datetime 值區開頭的 datetime 值,如果未指定源參數,則傳回 的預設原點值 1900-01-01 00:00:00.000
。
如需所有 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
論點
dayofyear、day 和 weekday 都會傳回相同的值。 每個 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 參數的引數
這些範例會使用不同的運算式類型,作為 number 和 date 參數的引數。 這些範例是使用 AdventureWorksDW2019
Database 所建置。
將使用者自訂變數指定為 number 和 date
此範例會將使用者定義變數指定為 number 和 date 的引數:
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)
,作為 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) 做為 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);