having()
The having() method adds a HAVING clause to your query, used to filter grouped results.
It supports aggregate functions, subquery aliases and grouped fields, and applies strict validation to prevent unsafe usage.
Signature:
public function having(string $columnOrAlias, mixed $value, string $operator = '='): self
Allowed Column Expressions
- Columns in groupBy() (e.g.
'user_id') ✅ - Aggregate functions like
COUNT(*),SUM(amount),AVG(score)✅ - Subquery aliases via
$db->subQuery('alias')✅ - Direct column names not in GROUP BY ❌
- Dangerous expressions like
'1 OR 1=1'❌
Supported Operators
=,!=,>,<,>=,<=BETWEEN,NOT BETWEEN→ requires array with exactly two valuesIN,NOT IN→ requires non-empty arrayIS,IS NOT→ only valid withnull(or'DBNULL','DBNOTNULL')
Special Values
'DBNULL'→ becomesIS NULL'DBNOTNULL'→ becomesIS NOT NULL- Subqueries, placeholders like
[F],[I]are validated and supported
Example with Aggregate Function
$db->groupBy('user_id');
$db->having('SUM(price)', 100, '>');
Example with BETWEEN
$db->groupBy('user_id');
$db->having('AVG(score)', [50, 80], 'BETWEEN');
Example with Subquery Alias
$sub = $db->subQuery('o');
$sub->get('orders');
$db->from($sub, 'user_stats');
$db->having('o', 100, '>');
Example with IS NOT NULL
$db->groupBy('customer_id');
$db->having('SUM(total)', 'DBNOTNULL', 'IS NOT');
Invalid Usage
The following will be rejected because email is not grouped, not aggregated, and not a valid alias:
// ❌ Unsafe
$db->having('email', 'x@example.com');