Column Calculations — Arithmetic & Expressions
Do math directly inside SQL — operators, precedence, integer division, ROUND, MOD, and building computed columns that power real business analytics
// Part 01
Why SQL Needs to Do Math
Databases store raw numbers — unit prices, quantities, salaries, order totals. But the numbers that drive business decisions are almost always derived — profit margin, GST-inclusive price, discount amount, days since order, salary as a percentage of the highest salary in the team. These are not stored anywhere. They are calculated on demand from the raw values.
SQL lets you perform these calculations directly in your SELECT statement. The result is a computed column that exists only in the query output — the underlying table is never changed. This is one of SQL's most powerful features: the database handles all the math, and you get clean, calculated results without exporting data to Excel and doing it manually.
// Part 02
The Five Arithmetic Operators
SQL supports five arithmetic operators for numeric calculations. They work on INTEGER, DECIMAL, FLOAT, and BIGINT columns — and on literal numbers you type directly in the query.
| Operator | Name | Example | Result | FreshMart use |
|---|---|---|---|---|
| + | Addition | 100 + 50 | 150 | unit_price + tax_amount |
| - | Subtraction | 100 - 30 | 70 | unit_price - cost_price (profit) |
| * | Multiplication | 100 * 1.18 | 118 | unit_price * quantity (line total) |
| / | Division | 100 / 4 | 25 | (profit / unit_price) * 100 (margin %) |
| % | Modulo | 10 % 3 | 1 | order_id % 2 (split into even/odd batches) |
Addition and subtraction
Multiplication
Division and modulo
// Part 03
Operator Precedence — The Order Calculations Run
SQL follows the same arithmetic precedence rules as mathematics. Multiplication and division run before addition and subtraction. Modulo has the same precedence as multiplication and division. Parentheses override everything.
The margin percentage mistake
This is the most common arithmetic precedence bug in SQL analytics. Getting the margin formula wrong produces silently incorrect results — the query runs fine but the numbers are wrong.
// Part 04
Integer Division — The Silent Truncation Bug
This is one of the most dangerous arithmetic bugs in SQL and it produces no error — just wrong answers. When you divide two integers in PostgreSQL and MySQL, the result is also an integer — the decimal part is silently discarded (truncated, not rounded).
The fix — force decimal division
Three ways to force the database to treat integer division as decimal division:
// Part 05
ROUND, CEIL, FLOOR, ABS — Controlling Numeric Output
Raw division results often have many decimal places. SQL provides built-in functions to control the precision of numeric output.
ROUND — round to N decimal places
CEIL — round up to the nearest integer
FLOOR — round down to the nearest integer
ABS — absolute value
// Part 06
Arithmetic in WHERE — Filtering on Calculated Values
You can use arithmetic expressions in WHERE conditions — not just in SELECT. This lets you filter rows based on calculated values without needing a subquery.
// Part 07
Arithmetic with Dates — Calculating Time Differences
Date arithmetic is one of the most frequent calculations in real analytics. How long did delivery take? How many days since a customer joined? How old is this record? SQL handles date arithmetic, though the syntax varies slightly between databases.
Date subtraction — days between two dates
Dialect differences for date arithmetic
// Part 08
Building Computed Columns — Real Business Analytics
The real power of arithmetic in SQL is building complex computed columns that answer business questions in a single query. Here are complete real-world examples.
Product profitability report
Order value analysis
Employee compensation analysis
// Part 09
Arithmetic Across Multiple Tables — Using Joins
The most powerful arithmetic queries combine data from multiple tables. You will learn JOINs in depth from Module 30, but here is a preview of how arithmetic works across joined tables — building revenue calculations that span orders, items, and products.
// Part 10
What This Looks Like at Work
You are a business analyst at Nykaa. The category management team wants a weekly SKU-level profitability report that their buyers use to make restocking decisions. The report needs to show each product's margin, GST-inclusive price, a margin band category, and a restock recommendation based on stock status and margin.
🎯 Pro Tip
The most valuable thing about arithmetic in SQL is that it is reproducible and documentable. Every calculation is visible in the query. A colleague can review it, modify the margin threshold from 0.30 to 0.35, rerun, and get updated results instantly. An Excel formula hidden in a cell is none of these things. When building reports for business teams, prefer SQL calculations over post-export Excel calculations — they are auditable, versionable, and shareable.
// Part 11
Interview Prep — 5 Questions With Complete Answers
SQL supports five arithmetic operators: addition (+), subtraction (-), multiplication (*), division (/), and modulo (%). Modulo returns the remainder after integer division — 10 % 3 returns 1 because 10 divided by 3 is 3 with a remainder of 1.
The precedence order mirrors standard mathematics: multiplication, division, and modulo are evaluated first (left to right when they appear together), then addition and subtraction (left to right). Parentheses override all precedence rules — expressions inside parentheses are always evaluated first, regardless of what operators are inside or outside them.
A practical precedence example: 10 + 5 * 2 evaluates as 10 + 10 = 20, not 15 * 2 = 30. To get 30, write (10 + 5) * 2. For margin percentage: unit_price - cost_price / unit_price * 100 is evaluated as unit_price - (cost_price / unit_price * 100), which is wrong. The correct formula requires parentheses: (unit_price - cost_price) / unit_price * 100. Precedence bugs in financial calculations are particularly dangerous because the query runs without error but produces incorrect numbers that may be used in business decisions.
Integer division occurs when both operands in a division expression are integers — the database returns an integer result, discarding the decimal portion. The result is truncated (not rounded): 7 / 2 returns 3 in PostgreSQL and MySQL, not 3.5. This is mathematically correct in integer arithmetic but almost never what SQL analysts intend when calculating ratios or percentages.
The danger is that no error occurs — the query runs successfully and returns results that appear plausible but are wrong. If a products table has INTEGER columns for unit_price and cost_price, the margin calculation (unit_price - cost_price) / unit_price would return 0 for every product where profit is less than the selling price — which is virtually every product. The analyst would see 0% margin across the board and have no indication that the division was truncated.
Three reliable solutions: multiply by 1.0 before dividing — (unit_price - cost_price) * 1.0 / unit_price — which promotes the result to decimal. Use CAST to explicitly convert to a decimal type — CAST(unit_price - cost_price AS DECIMAL) / unit_price. Or use a decimal literal in the numerator or denominator — (unit_price - cost_price) / 1.0. The CAST approach is most explicit about intent and is recommended in production code where the data types of columns may not be immediately obvious to someone reading the query later.
All three convert a decimal number to a controlled precision, but they round in different directions. ROUND(number, places) rounds to the specified number of decimal places using standard rounding — values ending in .5 or higher round up, below .5 round down. ROUND(3.45, 1) returns 3.5. ROUND(3.44, 1) returns 3.4. ROUND with a negative places argument rounds to the left of the decimal: ROUND(1234, -2) returns 1200.
CEIL (or CEILING) always rounds up to the nearest integer — away from zero for positive numbers. CEIL(4.1) returns 5. CEIL(4.9) returns 5. CEIL(4.0) returns 4. CEIL is used for "how many containers do I need?" problems — if you have 22 items and containers hold 10, you need CEIL(22/10) = 3 containers, not 2.2.
FLOOR always rounds down to the nearest integer — towards zero for positive numbers. FLOOR(4.9) returns 4. FLOOR(4.1) returns 4. FLOOR(4.0) returns 4. FLOOR is used for bucketing and banding — FLOOR(salary / 10000) * 10000 gives the bottom of each ₹10,000 salary band. The trio covers three essential rounding patterns: nearest value (ROUND), always up (CEIL), always down (FLOOR).
When arithmetic is applied to a column in a WHERE condition — WHERE unit_price * 1.18 >200 — the database must calculate unit_price * 1.18 for every single row in the table before it can determine whether the row qualifies. This prevents the database from using an index on unit_price, because the index stores raw unit_price values, not the result of unit_price * 1.18. The result is a full table scan even when the unit_price column has an index.
When the arithmetic is moved to the literal side — WHERE unit_price > 200 / 1.18 — the database evaluates 200 / 1.18 once (it is a constant, independent of any row), producing approximately 169.49. The WHERE condition becomes WHERE unit_price > 169.49, which the database can evaluate using an index on unit_price directly. Instead of a full table scan, the database does an index range scan — a dramatically more efficient operation on large tables.
This principle is called SARGability (Search ARGument Ability). A WHERE condition is SARGable if the database can use an index to satisfy it. Conditions that apply functions or arithmetic to columns are not SARGable. Conditions that compare raw column values to constants (even computed constants) are SARGable. The rule: whenever possible, isolate the column in the WHERE condition — put all transformations on the literal side. This applies to arithmetic, functions (LOWER, YEAR, MONTH), and any other operation that wraps a column value.
Date arithmetic in SQL calculates intervals between dates or adds/subtracts time from a date. The concept is universal — every SQL database supports it — but the syntax differs significantly across databases, which is one of the most common portability issues when moving SQL between systems.
In PostgreSQL and DuckDB (used in this playground), subtracting two DATE values returns an integer representing the number of days: delivery_date - order_date returns 2 if delivery was 2 days after the order. Adding an integer to a date adds that many days: order_date + 7 returns the date 7 days later. PostgreSQL also supports INTERVAL arithmetic: order_date + INTERVAL '1 month' adds exactly one month. In MySQL, date subtraction is done with the DATEDIFF function: DATEDIFF(delivery_date, order_date). Date addition uses DATE_ADD: DATE_ADD(order_date, INTERVAL 7 DAY). In SQL Server, DATEDIFF(day, order_date, delivery_date) for difference and DATEADD(day, 7, order_date) for addition.
The safest cross-database approach is to use explicit functions rather than operator overloading. DATEDIFF is supported in MySQL and SQL Server (with different argument order). PostgreSQL's date subtraction operator is elegant but PostgreSQL-specific. When writing SQL that must run on multiple database types, document which database it targets or use a database abstraction layer that normalises these differences. In practice, most organisations standardise on one database per workload, making dialect differences a concern primarily when migrating systems or working with multiple clients on different stacks.
// Part 12
Errors You Will Hit — And Exactly Why They Happen
🎯 Key Takeaways
- ✓SQL supports five arithmetic operators: + (add), - (subtract), * (multiply), / (divide), % (modulo). Arithmetic in SELECT creates computed columns — the table is never modified.
- ✓Operator precedence: multiplication, division, and modulo before addition and subtraction. Parentheses always override precedence. Use explicit parentheses for any non-trivial expression.
- ✓Integer division truncates the decimal portion silently — 7/2 returns 3, not 3.5, in PostgreSQL and MySQL. Force decimal division with CAST(value AS DECIMAL), multiply by 1.0, or use a decimal literal.
- ✓NULL propagates through arithmetic — any expression involving NULL returns NULL. Use COALESCE to substitute defaults before calculations: COALESCE(discount_pct, 0).
- ✓ROUND(number, places) rounds to N decimal places. CEIL always rounds up. FLOOR always rounds down. ABS returns the absolute value (removes negative sign).
- ✓Arithmetic in WHERE works but applying calculations to the column side (WHERE col * 1.18 > 200) prevents index usage. Move calculations to the literal side (WHERE col > 200 / 1.18) to keep queries SARGable.
- ✓Date subtraction returns days between two dates in PostgreSQL/DuckDB. Use DATEDIFF in MySQL. Use INTERVAL for calendar-aware month/year arithmetic — adding 30 days is not the same as adding one month.
- ✓Division by zero raises an error in PostgreSQL. Prevent it with NULLIF on the denominator: value / NULLIF(denominator, 0) — returns NULL instead of crashing when the denominator is zero.
- ✓Always use DECIMAL data types for monetary values — never FLOAT or DOUBLE. Floating-point representation errors in ROUND() accumulate into accounting discrepancies at scale.
- ✓Computed columns in SQL are reproducible, documentable, and reviewable. They are always preferable to post-export Excel calculations for business reporting.
What comes next
In Module 13, you learn aliases — giving columns and tables readable names with the AS keyword. Aliases make complex queries readable and are the foundation of every clean, maintainable SQL query you will ever write.
Module 13 → Renaming Columns — AS (Aliases)Discussion
0Have a better approach? Found something outdated? Share it — your knowledge helps everyone learning here.