Db2 SQLCODE

SQLCODE -119: Column or expression in HAVING not valid

SQLCODE -119 (SQLSTATE 42803) means a HAVING clause refers to a column or expression that is neither in the GROUP BY clause nor inside an aggregate function such as SUM or COUNT.

Other names for this code

Also written as SQL -119, SQLCODE=-119, SQLCODE = -119, db2 -119, sqlstate 42803, SQL0119N, column in having clause is not valid.

What it means

HAVING filters groups, not rows. By the time Db2 applies it, the rows have already been combined into one result per group. So HAVING can only use values that are the same for the whole group. Those are the grouping columns and expressions in GROUP BY, and aggregate functions such as SUM, COUNT, MAX and AVG, which turn the many rows of a group into one value.

A plain column that isn't in GROUP BY can have a different value on every row of a group, so a HAVING condition on it has no single answer. Db2 rejects the statement with -119.

A grouping expression counts only if it matches the GROUP BY expression exactly, apart from blanks. If you group by SUBSTR(DEPT, 1, 2), HAVING can use that same expression, but not DEPT on its own and not a different expression that happens to give the same result.

Common causes

  • A row-level condition written in HAVING instead of WHERE, such as HAVING JOB = 'MGR' when JOB isn't grouped.
  • A column added to HAVING but not to GROUP BY during a change to the query.
  • A HAVING expression that differs from the GROUP BY expression, for example LEFT(DEPT, 2) in HAVING and SUBSTR(DEPT, 1, 2) in GROUP BY.
  • A HAVING clause on a query with no GROUP BY that refers to a column outside an aggregate function.

How to find the problem

  1. Find the column named in SQLERRMC or the DSNT408I message, then check whether it appears in GROUP BY.
  2. If it does appear there inside an expression, compare the two expressions character for character.
  3. Ask what the condition is meant to do. If it tests individual rows, it belongs in WHERE. If it tests a total or count for the group, it needs an aggregate function.

How to fix it

  • Move row conditions to WHERE. WHERE JOB = 'MGR' GROUP BY DEPT HAVING SUM(SALARY) > 500000 filters rows first and groups second.
  • Wrap the column in the aggregate you mean, such as HAVING MAX(HIRE_DATE) < '2020-01-01'.
  • Add the column to GROUP BY if the groups really should be split by it.
  • Write grouping expressions the same way in GROUP BY and HAVING.

What it looks like

DSNT408I SQLCODE = -119, ERROR:  A COLUMN OR EXPRESSION IN A HAVING CLAUSE IS NOT VALID
DSNT418I SQLSTATE   = 42803 SQLSTATE RETURN CODE

IBM documentation

IBM documentation: -119. Use the documentation for your installed release.

Report a correction to WND Software.

Questions

What's the difference between WHERE and HAVING?

WHERE filters rows before they are grouped. HAVING filters the groups afterwards, so it can only use grouping columns and aggregate functions.

How is -119 different from -122?

Both have SQLSTATE 42803. -119 is about a bad column in HAVING. -122 is the same problem in the SELECT list or ORDER BY.

Is SQL0119N on Db2 for LUW the same?

It has the same SQLSTATE, 42803, and the same cause, though the LUW message is worded differently and also covers the SELECT list.