Skip to content

Beginner: asking questions · Functions, CASE and NULL · topic 12 of 62 · 30 min

Numbers and maths

Explanation

SQL does arithmetic with + − * / and % (the remainder). Dividing two whole numbers drops the fraction in SQLite, PostgreSQL and SQL Server, so 7 / 2 is 3; multiply by 1.0 or CAST to REAL to get 3.5. ROUND, ABS and CAST tidy the answers, which is how GST, discounts and percentages are worked out.

Why maths inside the database?

Reports need numbers that are not stored: a price with GST, a discount, a percentage, a daily rate from a monthly salary. Working them out in the query means every screen and report uses the same formula, and only the result travels to the app. In module 2 you met + − * / and ROUND; this topic goes deeper into the traps.

Integer division, again and properly

An integer is a whole number, like 7 or 95000. A real (or decimal) number has a fraction, like 3.5. When both sides of / are integers, SQLite, PostgreSQL and SQL Server give an integer answer and simply drop the fraction. MySQL and Oracle give a decimal answer.

sql
SELECT name, salary, salary / 30 AS wrong_day, ROUND(salary / 30.0, 2) AS day_pay
FROM employees WHERE id IN (3, 9);
-- Anita Desai | 95000 | 3166 | 3166.67
-- Neha Joshi  | 68000 | 2266 | 2266.67
salary / 30 loses the paise. Writing 30.0 makes one side a real number, so the answer keeps its fraction.
ExpressionSQLite / PostgreSQL / SQL ServerMySQL
7 / 233.5000
7 / 2.03.53.5000
7 * 1.0 / 23.53.5000
CAST(7 AS REAL) / 23.53.5 (7 / 2 is enough)
Whole-number division on purpose7 / 2 → 37 DIV 2 → 3
Tip: Order matters: marks * 100.0 / 120 is safe, but marks / 120 * 100.0 is not, because marks / 120 is worked out first as integer division and is already 0.

CAST: changing the type

CAST(value AS type) converts a value. CAST(7 AS REAL) gives 7.0, CAST('42' AS INTEGER) turns text into the number 42, and CAST(3.99 AS INTEGER) gives 3, because CAST cuts off the fraction instead of rounding. Use ROUND when you want rounding.

ROUND and ABS

ROUND(x, 2) keeps two decimal places; ROUND(x) keeps none. SQLite rounds halves away from zero, so ROUND(2.5) is 3 and ROUND(-2.5) is −3. ABS(x) gives the size of a number without its sign: ABS(−250) is 250, handy for the difference between two amounts when you do not care which is bigger.

sql
SELECT 1.1 + 2.2;            -- 3.3000000000000003
SELECT ROUND(1.1 + 2.2, 2);  -- 3.3
Real numbers are stored in binary, so tiny errors appear. Round money at the end of a calculation.
Careful: For money that must be exact (bank balances, invoices), many systems store paise as an INTEGER (₹1,060.82 is stored as 106082) or use a DECIMAL/NUMERIC column in PostgreSQL, MySQL and SQL Server. Floating-point REAL values are fine for reports, not for accounts.

% : the remainder

a % b gives what is left over after dividing a by b. 17 % 5 is 2. Two common uses: id % 2 = 0 picks even ids (useful to split rows into two groups), and stock % 6 gives the loose items after packing boxes of six. PostgreSQL, MySQL and Oracle also have MOD(a, b).

sql
SELECT name, stock, stock / 6 AS full_boxes, stock % 6 AS loose
FROM products WHERE id <= 3;
-- Basmati Rice 5kg | 40 | 6  | 4
-- Toor Dal 1kg     | 75 | 12 | 3
-- Steel Tiffin Box | 12 | 2  | 0
Here integer division is exactly what we want: whole boxes only.

GST and discount maths

  • GST amount: price * 0.18. Price with GST: price * 1.18.
  • A discount of d percent: price * (1 − d / 100.0). A 15% discount is price * 0.85.
  • Discount first, then GST: price * 0.9 * 1.18. Multiplication order does not change the answer, but say clearly in the report which came first.
  • Percentage of a total: part * 100.0 / total, then ROUND.
sql
SELECT name, price, ROUND(price * 0.18, 2) AS gst, ROUND(price * 1.18, 2) AS total
FROM products WHERE id IN (2, 5);
-- Toor Dal 1kg | 160 | 28.8   | 188.8
-- Cotton Kurta | 899 | 161.82 | 1060.82

Common mistakes

  • Integer division giving 0 or a cut-off answer. Put the 100.0 or 1.0 first: x * 100.0 / y.
  • Expecting CAST(3.99 AS INTEGER) to give 4. CAST cuts; ROUND rounds.
  • Rounding in the middle of a calculation and then adding: small differences pile up. Round the final value.
  • Comparing reals for exact equality: 1.1 + 2.2 = 3.3 is false in SQLite. Compare rounded values.
  • Dividing by a column that can be 0. Topic 5 shows NULLIF for that.

Need help?

Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.

Try:

Watch the lesson

Numbers and maths · 1/7

Numbers and maths

Reports need numbers that are not stored: GST, discounts, percentages, daily pay. SQL works them out row by row.

Prefer a video by a teacher? Find free videos on “sql arithmetic integer division cast round modulo tutorial” on YouTube ↗

In real life: Working out an invoice on a billing app

A billing app used by small shops stores each item's price and the discount on the bill. At checkout the query applies the discount, adds 18% GST and rounds to two places, so the printed bill, the shop's report and the GST summary all use one formula. Shops that need exact paise usually store amounts as integers in paise and divide by 100 only for display.

sql
SELECT name,
       price,
       ROUND(price * 0.9, 2)         AS after_discount,
       ROUND(price * 0.9 * 1.18, 2)  AS to_pay
FROM products
WHERE category = 'Fashion';
Cotton Kurta: 899 → 809.1 → 954.74. Running Shoes: 2499 → 2249.1 → 2653.94.

Practice (0/4 done)

Task 1 · Code · SQL

Sale day: Fashion products get 10% off, then 18% GST is added. Return name, price, and price * 0.9 * 1.18 rounded to 2 decimal places, named final_price, for products in the Fashion category.

Task 2 · Code · SQL

The exam was out of 120. Return name, marks, and the percentage (marks out of 120, times 100) rounded to 1 decimal place, named percent. Watch out for integer division.

Task 3 · Code · SQL

Split the class into two groups by id. Return id and name of students with an even id.

Task 4 · Code · SQL

The warehouse packs items in boxes of 6. From products, return name, stock, the number of full boxes named full_boxes, and the items left over named loose.

Quick quiz

Question 1

1.In SQLite, what does SELECT 45 / 120 * 100; return?

Question 2

2.What does CAST(9.99 AS INTEGER) return?

Question 3

3.Which expression gives the price after a 15% discount?

Question 4

4.What is 23 % 5?

Question 5

5.A query that works in MySQL returns 3.5 for 7 / 2, but 3 after moving to PostgreSQL with integer columns. Why?

Read more (free)

Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.

In SQLite, what does SELECT 45 / 120 * 100; return?

Answer: 0

45 / 120 is integer division and gives 0, and 0 * 100 is 0. Write 45 * 100.0 / 120 instead.

What does CAST(9.99 AS INTEGER) return?

Answer: 9

CAST cuts off the fraction; it does not round. Use ROUND(9.99) for 10.

Which expression gives the price after a 15% discount?

Answer: price * 0.85

Paying 85% of the price is the same as taking 15% off.

What is 23 % 5?

Answer: 3

23 = 4 × 5 + 3, so the remainder is 3.

A query that works in MySQL returns 3.5 for 7 / 2, but 3 after moving to PostgreSQL with integer columns. Why?

Answer: PostgreSQL integer / integer drops the fraction; MySQL's / always keeps it

Make one side a decimal (7 * 1.0 / 2, or CAST to numeric) so it works the same everywhere.

What does Math.Round(2.5) return in C#?Related

Answer: 2

By default C# uses banker's rounding: halfway values go to the nearest even number.

From Operators, conversions and parsing input

What type is the result of 3 + 2.0?Related

Answer: double

The int is converted to double.

From Type conversion and casting

What type does Math.round(2.5) return?Related

Answer: long

Math.round(double) returns a long (Math.round(float) returns int).

From Type conversion and reading input

What is static_cast<int>(9.99)?Related

Answer: 9

Converting a double to an int cuts off the fraction; it does not round.

From Variables, types and constants

Pass the quiz (60% or more) or mark this topic as done when you are ready.

Your progress is saved on this device only.

Next steps

  1. 3 more topics in “Functions, CASE and NULL” before its exam: Working with dates, CASE expressions, NULL: the missing value.
  2. Module 3 exam: Functions, CASE and NULL · 15 questions · 25 min, without help. 5 topics of this module still to finish first.
  3. Then the next module, Aggregation: GROUP BY and HAVING. 62 topics left in the course before the final exam.

← Previous: Text functions