Single-Row Functions

Lesson 0006 — ROUND, ABS, GREATEST/LEAST, IFNULL & COALESCE — ~16 min read

One row in, one value out. Single-row functions transform each row independently — rounding money, taking absolute values, picking the best test score, or replacing missing data — without collapsing rows like aggregates.

The Dataset — students

CREATE TABLE students (
  id INT PRIMARY KEY,
  name VARCHAR(40) NOT NULL,
  city VARCHAR(30) NULL,
  phone VARCHAR(20) NULL,
  fee_paid DECIMAL(10,2) NULL,     -- for ROUND()
  score_change DECIMAL(10,2) NULL, -- for ABS()
  test1 INT NULL,                  -- for GREATEST/LEAST
  test2 INT NULL, test3 INT NULL
);

INSERT INTO students (id, name, city, phone, fee_paid, score_change, test1, test2, test3) VALUES
(1,  'Aisha',   'Delhi',     NULL,           2804.45,  -12.25, 55, 60, 58),
(2,  'Rohan',   'Mumbai',    '',             3303.06,  -80.00, 40, NULL, 52),
(3,  'Meenal',  NULL,        '8888000004',   7999.00,   NULL,  NULL, NULL, 35),
(4,  'Arjun',   'Pune',      '9777000005',   3717.94,   10.00, 72, 70, 75),
(5,  'Neha',    'Jaipur',    NULL,           3499.00,  -30.75, 10, 15, 12),
(6,  'Vikas',   'Hyderabad', '9666000007',   5099.00,  120.75, 88, 91, 95),
(7,  'Sana',    'Ahmedabad', NULL,           7085.13,  -15.00, 65, 64, NULL),
(8,  'Imran',   'Kolkata',   '',             3303.06,   -1.00, 50, 49, 51),
(9,  'Pallavi', '',          '9555000010',   3303.06,    5.25, 92, 90, 91),
(10, 'Deepak',  'Chennai',   NULL,           NULL,     -22.00, 33, 40, 38),
(11, 'Ananya',  'Bengaluru', '9444000012',   3504.16,   18.50, 78, NULL, NULL),
(12, 'Tanya',   'Kolkata',   '',             3303.06,  -10.00, 45, 42, 48);
CREATE TABLE students (
  id INT PRIMARY KEY,
  name VARCHAR(40) NOT NULL,
  city VARCHAR(30),
  phone VARCHAR(20),
  fee_paid NUMERIC(10,2),
  score_change NUMERIC(10,2), test1 INT, test2 INT, test3 INT
);
-- same INSERT as SQL
idnamecityphonefee_paidscore_changetest1test2test3
1AishaDelhiNULL2804.45-12.25556058
2RohanMumbai''3303.06-80.0040NULL52
3MeenalNULL88880000047999.00NULLNULLNULL35
4ArjunPune97770000053717.9410.00727075
5NehaJaipurNULL3499.00-30.75101512
6VikasHyderabad96660000075099.00120.75889195
7SanaAhmedabadNULL7085.13-15.006564NULL
8ImranKolkata''3303.06-1.00504951
9Pallavi''95550000103303.065.25929091
10DeepakChennaiNULLNULL-22.00334038
11AnanyaBengaluru94440000123504.1618.5078NULLNULL
12TanyaKolkata''3303.06-10.00454248

1. ROUND() — Controlling Decimals

ROUND(number, decimals) rounds to the given decimal places. No decimals → nearest integer.

SELECT
  id, name, fee_paid,
  ROUND(fee_paid, 0) AS fee_rupees,
  ROUND(fee_paid, 2) AS fee_2dp
FROM students
ORDER BY id;
SELECT
  id, name, fee_paid,
  ROUND(fee_paid, 0) AS fee_rupees,
  ROUND(fee_paid, 2) AS fee_2dp
FROM students
ORDER BY id;
idnamefee_paidfee_rupeesfee_2dp
1Aisha2804.4528042804.45
2Rohan3303.0633033303.06
3Meenal7999.0079997999.00
4Arjun3717.9437183717.94
5Neha3499.0034993499.00
6Vikas5099.0050995099.00
7Sana7085.1370857085.13
8Imran3303.0633033303.06
9Pallavi3303.0633033303.06
10DeepakNULLNULLNULL
11Ananya3504.1635043504.16
12Tanya3303.0633033303.06

Standard rules: ≥ 0.5 rounds up, < 0.5 rounds down. NULL stays NULL.

2. ABS() — Absolute Value

ABS(number) returns distance from zero — negative → positive, positive stays, NULL stays NULL.

SELECT id, name, score_change, ABS(score_change) AS abs_score_change
FROM students
ORDER BY id;
SELECT id, name, score_change, ABS(score_change) AS abs_score_change
FROM students
ORDER BY id;
idnamescore_changeabs_score_change
1Aisha-12.2512.25
2Rohan-80.0080.00
3MeenalNULLNULL
4Arjun10.0010.00
5Neha-30.7530.75
6Vikas120.75120.75
7Sana-15.0015.00
8Imran-1.001.00
9Pallavi5.255.25
10Deepak-22.0022.00
11Ananya18.5018.50
12Tanya-10.0010.00

3. GREATEST() and LEAST() — Row-Wise Min/Max

GREATEST(a,b,…) returns the largest value in the list; LEAST(a,b,…) the smallest — computed per row across columns (not across rows like MAX). If any argument is NULL, result is NULL.

SELECT id, name, test1, test2, test3,
       GREATEST(test1, test2, test3) AS GREATEST_score,
       LEAST(test1, test2, test3)    AS LEAST_score
FROM students
ORDER BY id;
SELECT id, name, test1, test2, test3,
       GREATEST(test1, test2, test3) AS GREATEST_score,
       LEAST(test1, test2, test3)    AS LEAST_score
FROM students
ORDER BY id;
idnametest1test2test3GREATEST_scoreLEAST_score
1Aisha5560586055
2Rohan40NULL52NULLNULL
3MeenalNULLNULL35NULLNULL
4Arjun7270757570
5Neha1015121510
6Vikas8891959588
7Sana6564NULLNULLNULL
8Imran5049515149
9Pallavi9290919290
10Deepak3340384033
11Ananya78NULLNULLNULLNULL
12Tanya4542484842

Note: If any test column is NULL, result becomes NULL — use COALESCE(test2,0) if you need to treat missing as 0.

Why is GREATEST for Rohan NULL?

4. IFNULL() vs COALESCE() — Replacing Missing Values

IFNULL(expr, replacement) (MySQL) — if expr is NULL return replacement, else expr. Takes exactly 2 args. COALESCE(expr, …) — returns first non-NULL in the list (standard SQL, works in both MySQL and PostgreSQL).

IFNULL — MySQL only

SELECT id, name,
       IFNULL(phone, 'Not Provided') AS phone_status
FROM students;
SELECT id, name,
       COALESCE(phone, 'Not Provided') AS phone_status
FROM students;
idnamephone_status
1AishaNot Provided
2Rohan''
3Meenal8888000004
4Arjun9777000005
5NehaNot Provided
6Vikas9666000007
7SanaNot Provided
8Imran''
9Pallavi9555000010
10DeepakNot Provided
11Ananya9444000012
12Tanya''

Note: IFNULL only replaces NULL, not empty string ''. Rohan/Imran/Tanya have '' → stays ''.

NULL = missing/unknown; '' = present but empty — different.

Handling Both NULL and Empty Strings

Convert empty to NULL first with NULLIF, then replace:

SELECT id, name, phone,
       IFNULL(NULLIF(phone, ''), 'Not Provided') AS final_phone
FROM students;
SELECT id, name, phone,
       COALESCE(NULLIF(phone, ''), 'Not Provided') AS final_phone
FROM students;
idnamephonefinal_phone
1AishaNULLNot Provided
2Rohan''Not Provided
3Meenal88880000048888000004
4Arjun97770000059777000005
5NehaNULLNot Provided
6Vikas96660000079666000007
7SanaNULLNot Provided
8Imran''Not Provided
9Pallavi95550000109555000010
10DeepakNULLNot Provided
11Ananya94440000129444000012
12Tanya''Not Provided
  1. NULLIF(phone, '') → '' becomes NULL
  2. IFNULL(…, 'Not Provided') / COALESCE → NULL becomes replacement

5. COALESCE() — First Non-NULL Wins

COALESCE(v1, v2, …) returns the first non-NULL value in the list. Unlike IFNULL (2 args, MySQL-only), COALESCE takes many args and is standard SQL.

CREATE TABLE coalesce_demo (
  id INT PRIMARY KEY,
  primary_email   VARCHAR(80),
  work_email      VARCHAR(80),
  personal_email  VARCHAR(80),
  hours_logged    DECIMAL(10,2),
  default_hours   DECIMAL(10,2)
);

INSERT INTO coalesce_demo VALUES
(1, 'aisha@company.com', NULL,              'aisha@gmail.com',  5.0,  0.0),
(2, NULL,               'rohan@company.com',NULL,               NULL, 0.0),
(3, NULL,               NULL,               'meera@yahoo.com',  2.5,  0.0),
(4, NULL,               NULL,               NULL,              NULL, 0.0),
(5, '',                 NULL,               'raj@gmail.com',   5.0,  0.0);
CREATE TABLE coalesce_demo (
  id INT PRIMARY KEY,
  primary_email   VARCHAR(80),
  work_email      VARCHAR(80),
  personal_email  VARCHAR(80),
  hours_logged    DECIMAL(10,2),
  default_hours   DECIMAL(10,2)
);
-- same INSERT as SQL
idprimary_emailwork_emailpersonal_emailhours_loggeddefault_hours
1aisha@company.comNULLaisha@gmail.com5.00.0
2NULLrohan@company.comNULLNULL0.0
3NULLNULLmeera@yahoo.com2.50.0
4NULLNULLNULLNULL0.0
5''NULLraj@gmail.com5.00.0

Scenario 1: First Non-NULL Email

SELECT id,
       COALESCE(primary_email, work_email, personal_email) AS contact_email
FROM coalesce_demo;
SELECT id,
       COALESCE(primary_email, work_email, personal_email) AS contact_email
FROM coalesce_demo;
idCONTACT_EMAIL
1aisha@company.com
2rohan@company.com
3meera@yahoo.com
4NULL
5''
  1. COALESCE returns first non-NULL — id 4 (all NULL → NULL), id 5 ('' is not NULL → returns '')

Scenario 2: With Default

SELECT id,
       COALESCE(primary_email, work_email, personal_email, 'hello@tuf') AS contact_email
FROM coalesce_demo;
SELECT id,
       COALESCE(primary_email, work_email, personal_email, 'hello@tuf') AS contact_email
FROM coalesce_demo;
idCONTACT_EMAIL
1aisha@company.com
2rohan@company.com
3meera@yahoo.com
4hello@tuf
5''

Fallback 'hello@tuf' only for id 4 (all NULL). Empty string still returned as-is.

Scenario 3: COALESCE + NULLIF + TRIM — Skip Empty Too

SELECT id,
       COALESCE(NULLIF(TRIM(primary_email),''), work_email, personal_email) AS contact_email
FROM coalesce_demo;
SELECT id,
       COALESCE(NULLIF(TRIM(primary_email),''), work_email, personal_email) AS contact_email
FROM coalesce_demo;
idCONTACT_EMAIL
1aisha@company.com
2rohan@company.com
3meera@yahoo.com
4NULL
5raj@gmail.com
  1. TRIM(primary_email) removes spaces
  2. NULLIF(…, '') converts empty → NULL so COALESCE skips it → id 5 now correctly picks personal_email

IS NULL vs IS NOT NULL vs IFNULL vs COALESCE

ConceptDefinitionUsed inMySQL SyntaxPostgreSQL Syntax
IS NULLChecks if value is actually NULLWHERE (filter)col IS NULLcol IS NULL
IS NOT NULLChecks if value is presentWHERE (filter)col IS NOT NULLcol IS NOT NULL
IFNULL()Replaces NULL with value (2 args)SELECT (clean output)IFNULL(col, value)✖ Not available
COALESCE()Returns first non-NULL (many args)SELECT (clean output)COALESCE(col, value)COALESCE(col, value)
Common mistake= NULL never works — NULL is not a value—✖ col = NULL✖ col = NULL

IFNULL(phone,'Not Provided') vs COALESCE with NULLIF — which handles empty string?

Notes

Single-row functions :-

ROUND(fee_paid,0) → nearest rupee; ROUND(fee_paid,2) → 2 decimals; NULL stays NULL

ABS(score_change) → distance from 0; -80 → 80, NULL → NULL

GREATEST/LEAST per row across columns: GREATEST(55,60,58)=60; any NULL → NULL (≠ MAX aggregate)

IFNULL vs COALESCE :-

IFNULL(phone,'Not Provided') — MySQL, 2 args, only NULL; '' stays ''

COALESCE(phone, 'Not Provided') — standard, many args, first non-NULL wins

Handle '' too: IFNULL(NULLIF(phone,''),'Not Provided') / COALESCE(NULLIF(TRIM(primary_email),''), work_email…)

COALESCE demos :-

COALESCE(primary, work, personal) → first non-NULL; all NULL → NULL (id 4)

COALESCE(…, 'hello@tuf') → default fallback; '' still not NULL (id 5 → '')

COALESCE(NULLIF(TRIM(primary_email),''), …) → skips '' → id 5 → raj@gmail.com

IS NULL / IS NOT NULL filters rows; IFNULL/COALESCE cleans output; never use = NULL

Primary sources: MySQL Math Functions · Postgres Math · Postgres Conditional. Ask me anything that's unclear.

← Prev: Aggregation — GROUP BY, HAVING & COUNT Next: CASE Expressions →

Questions? Ask your agent — you can follow up on any concept, quiz answer, or how this applies to a specific query. Review the SQL glossary or syntax quick reference for a compressed overview.