Skip to content

Commit 8febdbe

Browse files
committed
(docs): Add documentation for aggregations, joins, distinct, union, raw, and helpers
1 parent 8ecb2b8 commit 8febdbe

1 file changed

Lines changed: 116 additions & 0 deletions

File tree

README.md

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,122 @@ $stmt->execute($result['bindings']);
314314
$rows = $stmt->fetchAll();
315315
```
316316

317+
**Aggregations** — count, sum, avg, min, max with optional aliases:
318+
319+
```php
320+
$result = (new Builder())
321+
->from('orders')
322+
->count('*', 'total')
323+
->sum('price', 'total_price')
324+
->select(['status'])
325+
->groupBy(['status'])
326+
->having([Query::greaterThan('total', 5)])
327+
->build();
328+
329+
// SELECT COUNT(*) AS `total`, SUM(`price`) AS `total_price`, `status`
330+
// FROM `orders` GROUP BY `status` HAVING `total` > ?
331+
```
332+
333+
**Distinct:**
334+
335+
```php
336+
$result = (new Builder())
337+
->from('users')
338+
->distinct()
339+
->select(['country'])
340+
->build();
341+
342+
// SELECT DISTINCT `country` FROM `users`
343+
```
344+
345+
**Joins** — inner, left, right, and cross joins:
346+
347+
```php
348+
$result = (new Builder())
349+
->from('users')
350+
->join('orders', 'users.id', 'orders.user_id')
351+
->leftJoin('profiles', 'users.id', 'profiles.user_id')
352+
->crossJoin('colors')
353+
->build();
354+
355+
// SELECT * FROM `users`
356+
// JOIN `orders` ON `users.id` = `orders.user_id`
357+
// LEFT JOIN `profiles` ON `users.id` = `profiles.user_id`
358+
// CROSS JOIN `colors`
359+
```
360+
361+
**Raw expressions:**
362+
363+
```php
364+
$result = (new Builder())
365+
->from('t')
366+
->filter([Query::raw('score > ? AND score < ?', [10, 100])])
367+
->build();
368+
369+
// SELECT * FROM `t` WHERE score > ? AND score < ?
370+
// bindings: [10, 100]
371+
```
372+
373+
**Union:**
374+
375+
```php
376+
$admins = (new Builder())->from('admins')->filter([Query::equal('role', ['admin'])]);
377+
$result = (new Builder())
378+
->from('users')
379+
->filter([Query::equal('status', ['active'])])
380+
->union($admins)
381+
->build();
382+
383+
// SELECT * FROM `users` WHERE `status` IN (?)
384+
// UNION SELECT * FROM `admins` WHERE `role` IN (?)
385+
```
386+
387+
**Conditional building**`when()` applies a callback only when the condition is true:
388+
389+
```php
390+
$result = (new Builder())
391+
->from('users')
392+
->when($filterActive, fn(Builder $b) => $b->filter([Query::equal('status', ['active'])]))
393+
->build();
394+
```
395+
396+
**Page helper** — page-based pagination:
397+
398+
```php
399+
$result = (new Builder())
400+
->from('users')
401+
->page(3, 10) // page 3, 10 per page → LIMIT 10 OFFSET 20
402+
->build();
403+
```
404+
405+
**Debug**`toRawSql()` inlines bindings for inspection (not for execution):
406+
407+
```php
408+
$sql = (new Builder())
409+
->from('users')
410+
->filter([Query::equal('status', ['active'])])
411+
->limit(10)
412+
->toRawSql();
413+
414+
// SELECT * FROM `users` WHERE `status` IN ('active') LIMIT 10
415+
```
416+
417+
**Query helpers** — merge, diff, and validate:
418+
419+
```php
420+
// Merge queries (later limit/offset/cursor overrides earlier)
421+
$merged = Query::merge($defaultQueries, $userQueries);
422+
423+
// Diff — queries in A not in B
424+
$unique = Query::diff($queriesA, $queriesB);
425+
426+
// Validate attributes against an allow-list
427+
$errors = Query::validate($queries, ['name', 'age', 'status']);
428+
429+
// Page helper — returns [limit, offset] queries
430+
[$limit, $offset] = Query::page(3, 10);
431+
```
432+
317433
**Pluggable extensions** — customize attribute mapping, identifier wrapping, and inject extra conditions:
318434

319435
```php

0 commit comments

Comments
 (0)