SQL Server 2022 T-SQL Features Worth Using: GREATEST, DATE_BUCKET, IS DISTINCT FROM and More
SQL Server 2022 added a set of small T-SQL features that quietly remove years of workarounds. None of them are headline features, but you will use them every week once you know they exist. Most need database compatibility level 160 and are also available in Azure SQL Database.

GREATEST and LEAST
SELECT EmployeeID,
GREATEST(LastLogin, LastPayslipView, LastProfileEdit) AS LastActivity,
LEAST(BasicPay, PayCap) AS CappedPay
FROM dbo.EmployeeActivity;
No more nested CASE expressions or VALUES tricks to find the max across columns. NULLs are ignored unless all arguments are NULL.
IS [NOT] DISTINCT FROM
SELECT * FROM dbo.Employees e
JOIN staging.Employees s ON s.EmployeeID = e.EmployeeID
WHERE e.Email IS DISTINCT FROM s.Email;
A NULL-safe comparison: two NULLs are treated as equal, NULL vs a value as different. Perfect for change detection without ISNULL(col, '') hacks.
DATETRUNC
SELECT DATETRUNC(MONTH, OrderDate) AS MonthStart, SUM(Amount)
FROM dbo.Orders
GROUP BY DATETRUNC(MONTH, OrderDate);
Truncates a date to year, quarter, month, week, day, hour and so on, replacing the old DATEADD(MONTH, DATEDIFF(MONTH, 0, d), 0) idiom.
DATE_BUCKET
SELECT DATE_BUCKET(MINUTE, 15, EventTime) AS Slot, COUNT(*)
FROM dbo.ApiCalls
GROUP BY DATE_BUCKET(MINUTE, 15, EventTime);
Groups times into fixed-width buckets (every 15 minutes, every 2 weeks). Great for monitoring and time-series charts.
The WINDOW clause
SELECT EmployeeID, PayPeriod, GrossPay,
SUM(GrossPay) OVER w AS RunningTotal,
AVG(GrossPay) OVER w AS RunningAvg
FROM dbo.Payslips
WINDOW w AS (PARTITION BY EmployeeID ORDER BY PayPeriod
ROWS UNBOUNDED PRECEDING);
Define a window once and reuse it, instead of repeating the same OVER clause.
STRING_SPLIT with ordinal, and TRIM with characters
SELECT value, ordinal FROM STRING_SPLIT('a,b,c', ',', 1);
SELECT TRIM('0' FROM '000123000'); -- '123'
SELECT LTRIM('xxABC', 'x'); -- 'ABC'
The new enable_ordinal argument finally tells you the position of each item.
GENERATE_SERIES
SELECT value FROM GENERATE_SERIES(1, 12);
Produces a sequence of numbers without a tally table or recursive CTE.
JSON improvements
SELECT JSON_OBJECT('id': EmployeeID, 'name': Name) FROM dbo.Employees;
SELECT JSON_ARRAY(1, 2, 3);
SELECT * FROM dbo.Events WHERE ISJSON(Payload, OBJECT) = 1;
JSON_OBJECT and JSON_ARRAY build JSON directly, and ISJSON can check the type.
APPROX_PERCENTILE_CONT
Approximate median and percentiles on huge tables using very little memory, ideal for dashboards where exactness to the last row does not matter.
How to start using them
ALTER DATABASE CURRENT SET COMPATIBILITY_LEVEL = 160;
Raise the level carefully (with Query Store watching for plan regressions), then start replacing old workarounds as you touch the code.
Related reading:
Comments
Post a Comment