SQL Server Built-in Functions: String, Date, and Math Functions You’ll Use Daily

SQL Server Built-in Functions: String, Date, and Math Functions You’ll Use Daily

Beyond aggregates, SQL Server ships a huge library of scalar functions — functions that take input and return one value per row, rather than collapsing many rows into one. Here are the ones you’ll actually reach for constantly, with the specific edge cases that catch people off guard.

Before → Function → After(three scalar transforms, same shape)‘DataForge’beforeUPPER()‘DATAFORGE’afterDec 31 → Jan 11 day apartDATEDIFF(YEAR,..)returns 1boundary crossed, not 365 days!7 / 2both operands INTinteger division3fractional part silently droppedTwo silent gotchas here:DATEDIFF counts boundariescrossed, not elapsed time —and INT / INT truncates,it doesn’t round. Cast toDECIMAL when it matters.

String Functions

SELECT UPPER(name), LOWER(name), LEN(name) FROM dbo.Startup;
SELECT CONCAT(name, ' (', industry, ')') AS label FROM dbo.Startup;
SELECT SUBSTRING(name, 1, 4) FROM dbo.Startup;
SELECT TRIM('  padded  ') AS cleaned;
SELECT REPLACE(name, 'Data', 'Info') FROM dbo.Startup;
SELECT LEFT(name, 3), RIGHT(name, 3) FROM dbo.Startup;
Common mistake: Using + to concatenate strings when one side might be NULL — first_name + ' ' + last_name returns NULL for the entire expression if either piece is NULL. CONCAT() treats NULL as an empty string instead, which is almost always what you actually want: CONCAT(first_name, ' ', last_name).

Date Functions

SELECT GETDATE() AS right_now;              -- current date + time
SELECT SYSDATETIME() AS right_now_precise;  -- higher precision, preferred in new code
SELECT YEAR(GETDATE()) AS current_year;
SELECT DATEDIFF(YEAR, '2020-01-01', GETDATE()) AS years_since_2020;
SELECT DATEADD(MONTH, 6, GETDATE()) AS six_months_from_now;
SELECT DATENAME(WEEKDAY, GETDATE()) AS day_name;  -- e.g. 'Friday'
Common mistake: DATEDIFF(YEAR, ...) counts calendar-year boundaries crossed, not full 365-day years. DATEDIFF(YEAR, '2020-12-31', '2021-01-01') returns 1, even though only one day actually passed — because a year boundary (Dec 31 → Jan 1) was crossed. This surprises almost everyone the first time they compute an “age” this way and get a value that’s off by one right around a birthday or anniversary.

Math and Rounding Functions

SELECT ROUND(funding_usd / 1000000.0, 2) AS funding_millions FROM dbo.Startup;
SELECT CEILING(4.1) AS rounds_up;   -- 5
SELECT FLOOR(4.9) AS rounds_down;   -- 4
SELECT ABS(-42) AS absolute_value;  -- 42

The Integer Division Trap

SELECT 7 / 2 AS wrong_answer;      -- 3, NOT 3.5 — both operands are INT, result truncates
SELECT 7.0 / 2 AS correct_answer;  -- 3.5 — forcing one operand to a decimal type fixes it
SELECT CAST(7 AS DECIMAL(10,2)) / 2 AS also_correct;
Common mistake: Dividing two INT columns and expecting a decimal result. SQL Server (like most languages) performs integer division when both operands are integers — the fractional part is silently discarded, not rounded, with no error or warning. This is a genuinely common source of “my percentage calculation shows 0” bugs. Always cast at least one side to a decimal type when division needs to be exact.

NULL-Handling and Conversion Functions

SELECT ISNULL(NULL, 'fallback value') AS demo;               -- returns 'fallback value'
SELECT COALESCE(NULL, NULL, 'third option') AS demo2;        -- returns 'third option'
SELECT CAST(funding_usd AS BIGINT) AS funding_rounded FROM dbo.Startup;
SELECT TRY_CAST('not a number' AS INT) AS safe_conversion;   -- returns NULL, not an error

TRY_CAST (and its cousin TRY_CONVERT) return NULL instead of throwing an error when a conversion fails — invaluable when converting messy, real-world data where you can’t guarantee every value is well-formed.

Quick Reference

Function Does
LEN() Character length of a string
CONCAT() Joins strings, treating NULL as empty rather than poisoning the whole result
DATEDIFF() Difference between two dates in a given unit — counts boundaries crossed, not elapsed duration
ROUND() Rounds a number to N decimal places
ISNULL() / COALESCE() Replaces NULL with a fallback value
TRY_CAST() / TRY_CONVERT() Converts types, returning NULL instead of erroring on bad input
Practice tip: Write a query that calculates each startup’s funding per employee (funding_usd / employees), formatted to 2 decimal places. Notice you need to think about integer division here too if employees were an INT divided by another INT — it isn’t in this case since funding_usd is DECIMAL, but it’s worth confirming that for yourself by checking the result type.

Enjoyed this?

Subscribe to get every new SQL Server lesson as soon as it’s published, and share it with a developer who’d find it useful.

📡 Subscribe via RSS  | 
Share on X  | 
Share on LinkedIn  | 
Share on Facebook

Want the full structured course with quizzes, projects, and 10+ exercises per chapter? Check out SQL Server Fundamentals, coming soon on this site.