|
| 1 | +--- |
| 2 | +title: Date_Bucket (Transact-SQL) - Azure SQL Edge |
| 3 | +description: Learn about using Date_Bucket in SQL Edge |
| 4 | +keywords: Date_Bucket, SQL Edge |
| 5 | +services: sql-database-edge |
| 6 | +ms.service: sql-database-edge |
| 7 | +ms.topic: reference |
| 8 | +author: SQLSourabh |
| 9 | +ms.author: sourabha |
| 10 | +ms.reviewer: sstein |
| 11 | +ms.date: 05/03/2019 |
| 12 | +--- |
| 13 | + |
| 14 | +# Date_Bucket (Transact-SQL) |
| 15 | + |
| 16 | +This function distributes aggregate column expressions in different date or time boundaries. |
| 17 | + |
| 18 | +See [Date and Time Data Types and Functions (Transact-SQL)](/sql/t-sql/functions/date-and-time-data-types-and-functions-transact-sql/) for an overview of all Transact-SQL date and time data types and functions. |
| 19 | + |
| 20 | +[Transact-SQL Syntax Conventions](/sql/t-sql/language-elements/transact-sql-syntax-conventions-transact-sql/) |
| 21 | + |
| 22 | +`DATE_BUCKET` uses a default origin date value of `1900-01-01 00:00:00.000` for example, 12 AM on Monday the 1 January 1900. |
| 23 | + |
| 24 | +## Syntax |
| 25 | + |
| 26 | +```sql |
| 27 | +DATE_BUCKET (datePart, number, date) |
| 28 | +``` |
| 29 | + |
| 30 | +## Arguments |
| 31 | + |
| 32 | +*datePart* |
| 33 | + |
| 34 | +The part of *date* that is used with the ‘number’ parameter. Ex. Year, month, minute, second etc. |
| 35 | + |
| 36 | +> [!NOTE] |
| 37 | +> `DATE_BUCKET` does not accept user-defined variable equivalents for the *datepPart* arguments. |
| 38 | + |
| 39 | +|*datePart*|Abbreviations| |
| 40 | +|---|---| |
| 41 | +|**dayofyear**|**dy**, **y**| |
| 42 | +|**day**|**dd**, **d**| |
| 43 | +|**week**|**wk**, **ww**| |
| 44 | +|**weekday**|**dw**, **w**| |
| 45 | +|**hour**|**hh**| |
| 46 | +|**minute**|**mi**, **n**| |
| 47 | +|**second**|**ss**, **s**| |
| 48 | +|**millisecond**|**ms**| |
| 49 | +|**microsecond**|**mcs**| |
| 50 | +|**nanosecond**|**ns**| |
| 51 | + |
| 52 | +*number* |
| 53 | +2 |
| 54 | +The integer number that decides the width of the bucket combined with *datePart* argument. This represents the width of the dataPart buckets from the origin time. |
| 55 | + |
| 56 | +*date* |
| 57 | + |
| 58 | +An expression that can resolve to one of the following values: |
| 59 | + |
| 60 | ++ **date** |
| 61 | ++ **datetime** |
| 62 | ++ **datetimeoffset** |
| 63 | ++ **datetime2** |
| 64 | ++ **smalldatetime** |
| 65 | ++ **time** |
| 66 | + |
| 67 | +For *date*, `DATE_BUCKET` will accept a column expression, expression, or user-defined variable if they resolve to any of the data types mentioned above. |
| 68 | + |
| 69 | +## Return Type |
| 70 | + |
| 71 | +The return value data type for this method is dynamic. The return type depends on the argument supplied for `date`. If a valid input data type is supplied for `date`, `DATE_BUCKET` returns the same data type. `DATE_BUCKET` raises an error if a string literal is specified for the `date` parameter. |
| 72 | + |
| 73 | +## Return Values |
| 74 | + |
| 75 | +### Understanding the output from `DATE_BUCKET` |
| 76 | + |
| 77 | +`Data_Bucket` returns the latest date or time value, corresponding to the datePart and number parameter. For example, in the expressions below, `Date_Bucket` will return the output value of `2020-04-13 00:00:00.0000000`, as the output is calculated based on one week buckets from the default origin time of `1900-01-01 00:00:00.000`. The value `2020-04-13 00:00:00.0000000` is 6276 weeks from the origin value of `1900-01-01 00:00:00.000`. |
| 78 | + |
| 79 | +```sql |
| 80 | +declare @date datetime2 = '2020-04-15 21:22:11' |
| 81 | +Select DATE_BUCKET(wk, 1, @date) |
| 82 | +``` |
| 83 | + |
| 84 | +For all the expressions below, the same output value of `2020-04-13 00:00:00.0000000` will be returned. This is because `2020-04-13 00:00:00.0000000` is 6276 weeks from the origin date and 6276 is divisible by 2, 3, 4 and 6. |
| 85 | + |
| 86 | +```sql |
| 87 | +declare @date datetime2 = '2020-04-15 21:22:11' |
| 88 | +Select DATE_BUCKET(wk, 2, @date) |
| 89 | +Select DATE_BUCKET(wk, 3, @date) |
| 90 | +Select DATE_BUCKET(wk, 4, @date) |
| 91 | +Select DATE_BUCKET(wk, 6, @date) |
| 92 | +``` |
| 93 | + |
| 94 | +The output for the expression below, which is 6275 weeks from the origin time. |
| 95 | + |
| 96 | +```sql |
| 97 | +declare @date datetime2 = '2020-04-15 21:22:11' |
| 98 | +Select DATE_BUCKET(wk, 5, @date) |
| 99 | +``` |
| 100 | + |
| 101 | +## datepart Argument |
| 102 | + |
| 103 | +**dayofyear**, **day**, and **weekday** return the same value. Each *datepart* and its abbreviations return the same value. |
| 104 | + |
| 105 | +## number Argument |
| 106 | + |
| 107 | +The *number* argument cannot exceed the range of **int**. In the following statements, the argument for *number* exceeds the range of **int** by 1. The following statement returns the following error message: "`Msg 8115, Level 16, State 2, Line 2. Arithmetic overflow error converting expression to data type int."` |
| 108 | + |
| 109 | +```sql |
| 110 | +declare @date datetime2 = '2020-04-30 00:00:00' |
| 111 | +Select DATE_BUCKET(dd, 2147483648, @date) |
| 112 | +``` |
| 113 | + |
| 114 | +## date Argument |
| 115 | + |
| 116 | +`DATE_BUCKET` return the base value corresponding to the data type of the `date` argument. If the expression evaluation returns in a datetime overflow, `DATE_BUCKET` will return the default origin time of `1900-01-01 00:00:00.0000000`. For example, the first statement will return an error "`Msg 517, Level 16, State 3, Line 1 Adding a value to a 'datetime2' column caused an overflow."`, while the second statement will return the value `1900-01-01 00:00:00.0000000` |
| 117 | + |
| 118 | +```sql |
| 119 | +Select DATEADD(dd, -2147483646, SYSUTCDATETIME()) |
| 120 | +Select DATE_BUCKET(dd, 2147483646, SYSUTCDATETIME()) |
| 121 | +``` |
| 122 | + |
| 123 | +## Remarks |
| 124 | + |
| 125 | +Use `DATE_BUCKET` in the following clauses: |
| 126 | + |
| 127 | ++ GROUP BY |
| 128 | ++ HAVING |
| 129 | ++ ORDER BY |
| 130 | ++ SELECT \<list> |
| 131 | ++ WHERE |
| 132 | + |
| 133 | +## Examples |
| 134 | + |
| 135 | +### A. Calculating Date_Bucket with a bucket width of 1 from the origin time |
| 136 | + |
| 137 | +Each of these statements increments *data_bucket* with a bucket width of 1 from the origin time: |
| 138 | + |
| 139 | +```sql |
| 140 | +declare @date datetime2 = '2020-04-30 21:21:21' |
| 141 | +Select 'Week', DATE_BUCKET(wk, 1, @date) |
| 142 | +Union All |
| 143 | +Select 'Day', DATE_BUCKET(dd, 1, @date) |
| 144 | +Union All |
| 145 | +Select 'Hour', DATE_BUCKET(hh, 1, @date) |
| 146 | +Union All |
| 147 | +Select 'Minutes', DATE_BUCKET(mi, 1, @date) |
| 148 | +Union All |
| 149 | +Select 'Seconds', DATE_BUCKET(ss, 1, @date) |
| 150 | +``` |
| 151 | + |
| 152 | +Here is the result set. |
| 153 | + |
| 154 | +```sql |
| 155 | +Week 2020-04-27 00:00:00.0000000 |
| 156 | +Day 2020-04-30 00:00:00.0000000 |
| 157 | +Hour 2020-04-30 21:00:00.0000000 |
| 158 | +Minutes 2020-04-30 21:21:00.0000000 |
| 159 | +Seconds 2020-04-30 21:21:21.0000000 |
| 160 | +``` |
| 161 | + |
| 162 | +### B. Using expressions as arguments for the number and date parameters |
| 163 | + |
| 164 | +These examples use different types of expressions as arguments for the *number* and *date* parameters. These examples are built using the 'AdventureWorksDW2017' Database. |
| 165 | + |
| 166 | +#### Specifying user-defined variables as number and date |
| 167 | + |
| 168 | +This example specifies user-defined variables as arguments for *number* and *date*: |
| 169 | + |
| 170 | +```sql |
| 171 | +DECLARE @days int = 365, |
| 172 | + @datetime datetime2 = '2000-01-01 01:01:01.1110000'; /* 2000 was a leap year */; |
| 173 | +SELECT Date_Bucket(day, @days, @datetime); |
| 174 | +``` |
| 175 | + |
| 176 | +Here is the result set. |
| 177 | + |
| 178 | +```sql |
| 179 | +--------------------------- |
| 180 | +1999-12-08 00:00:00.0000000 |
| 181 | + |
| 182 | +(1 row affected) |
| 183 | +``` |
| 184 | + |
| 185 | +#### Specifying a column as date |
| 186 | + |
| 187 | +In the example below, we are calculating the sum of OrderQuantity and sum of UnitPrice grouped over weekly date buckets. |
| 188 | + |
| 189 | +```sql |
| 190 | +SELECT |
| 191 | + Date_Bucket(week, 1 ,cast(Shipdate as datetime2)) AS ShippedDateBucket |
| 192 | + ,Sum(OrderQuantity) As SumOrderQuantity |
| 193 | + ,Sum(UnitPrice) As SumUnitPrice |
| 194 | +FROM dbo.FactInternetSales FIS |
| 195 | +where Shipdate between '2011-01-03 00:00:00.000' and '2011-02-28 00:00:00.000' |
| 196 | +Group by Date_Bucket(week, 1 ,cast(Shipdate as datetime2)) |
| 197 | +order by 1 |
| 198 | +``` |
| 199 | + |
| 200 | +Here is the result set. |
| 201 | + |
| 202 | +```sql |
| 203 | +ShippedDateBucket SumOrderQuantity SumUnitPrice |
| 204 | +--------------------------- ---------------- --------------------- |
| 205 | +2011-01-03 00:00:00.0000000 21 65589.7546 |
| 206 | +2011-01-10 00:00:00.0000000 27 89938.5464 |
| 207 | +2011-01-17 00:00:00.0000000 31 104404.9064 |
| 208 | +2011-01-24 00:00:00.0000000 36 118525.6846 |
| 209 | +2011-01-31 00:00:00.0000000 39 123555.431 |
| 210 | +2011-02-07 00:00:00.0000000 35 109342.351 |
| 211 | +2011-02-14 00:00:00.0000000 32 107804.8964 |
| 212 | +2011-02-21 00:00:00.0000000 37 119456.3428 |
| 213 | +2011-02-28 00:00:00.0000000 9 28968.6982 |
| 214 | +``` |
| 215 | + |
| 216 | +#### Specifying scalar system function as date |
| 217 | + |
| 218 | +This example specifies `SYSDATETIME` for *date*. The exact value returned depends on the |
| 219 | +day and time of statement execution: |
| 220 | + |
| 221 | +```sql |
| 222 | +SELECT Date_Bucket(wk, 10, SYSDATETIME()); |
| 223 | +``` |
| 224 | + |
| 225 | +Here is the result set. |
| 226 | + |
| 227 | +```sql |
| 228 | +--------------------------- |
| 229 | +2020-03-02 00:00:00.0000000 |
| 230 | + |
| 231 | +(1 row affected) |
| 232 | +``` |
| 233 | + |
| 234 | +#### Specifying scalar subqueries and scalar functions as number and date |
| 235 | + |
| 236 | +This example uses scalar subqueries, `MAX(OrderDate)`, as arguments for *number* and *date*. `(SELECT top 1 CustomerKey FROM dbo.DimCustomer where GeographyKey > 100)` serves as an artificial argument for the number parameter, to show how to select a *number* argument from a value list. |
| 237 | + |
| 238 | +```sql |
| 239 | +SELECT DATE_BUCKET(week,(SELECT top 1 CustomerKey FROM dbo.DimCustomer where GeographyKey > 100), |
| 240 | + (SELECT MAX(OrderDate) FROM dbo.FactInternetSales)); |
| 241 | +``` |
| 242 | + |
| 243 | +#### Specifying numeric expressions and scalar system functions as number and date |
| 244 | + |
| 245 | +This example uses a numeric expression (-`(10/2))`, and scalar system functions (`SYSDATETIME`) as arguments for *number* and *date*. |
| 246 | + |
| 247 | +```sql |
| 248 | +SELECT Date_Bucket(week,-(10/2), SYSDATETIME()); |
| 249 | +``` |
| 250 | + |
| 251 | +#### Specifying an aggregate window function as number |
| 252 | + |
| 253 | +This example uses an aggregate window function as an argument for *number*. |
| 254 | + |
| 255 | +```sql |
| 256 | +Select |
| 257 | + DISTINCT DATE_BUCKET(day, 30, Cast([shipdate] as datetime2)) as DateBucket, |
| 258 | + First_Value([SalesOrderNumber]) OVER (Order by DATE_BUCKET(day, 30, Cast([shipdate] as datetime2))) as First_Value_In_Bucket, |
| 259 | + Last_Value([SalesOrderNumber]) OVER (Order by DATE_BUCKET(day, 30, Cast([shipdate] as datetime2))) as Last_Value_In_Bucket |
| 260 | + from [dbo].[FactInternetSales] |
| 261 | +Where ShipDate between '2011-01-03 00:00:00.000' and '2011-02-28 00:00:00.000' |
| 262 | +order by DateBucket |
| 263 | +GO |
| 264 | +``` |
| 265 | + |
| 266 | +## See also |
| 267 | + |
| 268 | +[CAST and CONVERT (Transact-SQL)](/sql/t-sql/functions/cast-and-convert-transact-sql/) |
0 commit comments