All 40 lessons

Lesson 10 of 40 · SQL Functions

SQL Numeric Functions and CAST

By Skillancy Editorial Team

Every example runs on the ShopKart dataset, already loaded in the free SQL Compiler. Click Try it in the SQL Compiler under a query to open it there, then press Run.

SQL can do arithmetic directly in a query: calculate margins, apply discounts, round to rupees, and convert between data types. This lesson covers the operators and functions you'll use for nearly every metric.

Arithmetic operators

OperatorMeaningExampleResult
+ - * /add, subtract, multiply, divide2499 * 24998
%remainder (modulo)17 % 52
^power (PostgreSQL)2 ^ 101024

Common functions

FunctionWhat it doesExampleResult
ROUND(x, d)round to d decimalsROUND(123.456, 1)123.5
CEIL(x)round upCEIL(4.1)5
FLOOR(x)round downFLOOR(4.9)4
ABS(x)absolute valueABS(-250)250
MOD(a, b)remainderMOD(17, 5)2
CAST(x AS type)convert typeCAST('42' AS INT)42

Examples

1. Net amount after discount

Each order line has a discount_pct. Net revenue is quantity * unit_price * (1 - discount_pct / 100):

SELECT order_item_id,
       quantity,
       unit_price,
       discount_pct,
       quantity * unit_price * (1 - discount_pct / 100) AS net_amount
FROM order_items
LIMIT 5;
Try it in the SQL Compiler

Result:

order_item_idquantityunit_pricediscount_pctnet_amount
1123999.0010.0021599.1000000000000000000000
221299.000.002598.0000000000000000000000
318499.005.008074.0500000000000000000000
4131990.0015.0027191.5000000000000000000000
53549.000.001647.0000000000000000000000

(5 rows)

PostgreSQL keeps full precision when it multiplies decimals, hence the long tails on net_amount. That's exactly what ROUND is for.

2. ROUND to make results readable

Margin percentage, rounded to one decimal place:

SELECT product_name,
       ROUND((price - cost_price) / price * 100, 1) AS margin_pct
FROM products
ORDER BY margin_pct DESC
LIMIT 5;
Try it in the SQL Compiler

Result:

product_namemargin_pct
Yoga Mat 6mm56.2
Herbal Face Wash54.8
Steel Water Bottle 1L54.5
Men's Cotton Kurta50.0
The Psychology of Money49.8

(5 rows)

3. CEIL and FLOOR

ShopKart packs water bottles 6 per carton. How many cartons do we need for current stock, and how many full cartons can we fill?

SELECT product_name,
       stock_qty,
       CEIL(stock_qty / 6.0) AS cartons_needed,
       FLOOR(stock_qty / 6.0) AS full_cartons,
       stock_qty % 6 AS loose_units
FROM products
WHERE product_id IN (108, 110);
Try it in the SQL Compiler

Result:

product_namestock_qtycartons_neededfull_cartonsloose_units
Steel Water Bottle 1L30050500
Herbal Face Wash50084832

(2 rows)

4. The integer division trap

When both numbers are integers, PostgreSQL drops the decimals:

SELECT 7 / 2 AS integer_division,
       7 / 2.0 AS decimal_division,
       7::numeric / 2 AS cast_division;
Try it in the SQL Compiler

Result:

integer_divisiondecimal_divisioncast_division
33.50000000000000003.5000000000000000

(1 row)

This bites hardest in ratios. What share of orders were cancelled?

SELECT COUNT(*) FILTER (WHERE status = 'Cancelled') / COUNT(*) AS wrong_ratio,
       ROUND(COUNT(*) FILTER (WHERE status = 'Cancelled') * 100.0 / COUNT(*), 1) AS cancel_pct
FROM orders;
Try it in the SQL Compiler

Result:

wrong_ratiocancel_pct
08.3

(1 row)

COUNT returns integers, so 2 / 24 becomes 0. Multiplying by 100.0 first turns the calculation into decimal maths. (FILTER is explained in the aggregate functions lesson.)

5. CAST between types

SELECT CAST('2499' AS INT) + 1 AS text_to_int,
       CAST(23999.75 AS INT) AS numeric_to_int,
       CAST(order_date AS TEXT) AS date_as_text,
       order_date::text AS shortcut
FROM orders
LIMIT 1;
Try it in the SQL Compiler

Result:

text_to_intnumeric_to_intdate_as_textshortcut
2500240002025-01-052025-01-05

(1 row)

Note that casting 23999.75 to INT rounds it to 24000 in PostgreSQL rather than chopping off the decimals.

Common mistakes

  • Integer division in percentages. Use 100.0 or cast to numeric.
  • Rounding too early. Round only in the final SELECT. Rounding each line and then summing gives a slightly different total.
  • Using FLOAT for money. Floating-point types store approximations. Use NUMERIC(10,2) for rupees and paise.

Practice question

For each product, show the price, the GST at 18% rounded to whole rupees, and the final price.

Show solution
SELECT product_name,
       price,
       ROUND(price * 0.18) AS gst,
       price + ROUND(price * 0.18) AS final_price
FROM products
LIMIT 4;
Try it in the SQL Compiler

Result:

product_namepricegstfinal_price
Redmi Note 13 Pro23999.00432028319.00
boAt Airdopes 1411299.002341533.00
Samsung 43" Smart TV31990.00575837748.00
Men's Cotton Kurta1899.003422241.00

(4 rows)

Key takeaways

  • Arithmetic works directly in SELECT, WHERE and ORDER BY.
  • ROUND, CEIL and FLOOR control decimals.
  • Integer ÷ integer drops decimals in PostgreSQL; use 100.0 or ::numeric.
  • CAST(x AS type) (or x::type) converts between data types.

Frequently asked questions

Why does 5 / 2 return 2 in SQL?

When both numbers are integers, PostgreSQL and SQL Server do integer division and drop the decimal part. Cast one side to a decimal, for example 5 / 2.0 or 5::numeric / 2, to get 2.5. MySQL returns 2.5 by default.

What is the difference between CAST and ::?

They do the same thing. CAST(x AS numeric) is standard SQL and works everywhere; x::numeric is a PostgreSQL shortcut.

How do I round to 2 decimal places in SQL?

Use ROUND(value, 2). In PostgreSQL the two-argument version needs a numeric value, so write ROUND(value::numeric, 2) if the input is a floating-point number.

Newsletter

Keep learning SQL

One email a week with SQL and analytics guides, new practice questions and cohort dates. No spam, unsubscribe anytime.

Prefer a one-page summary? Download the free SQL cheat sheet (PDF)