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');