(PHP 8 >= 8.4.0)
Pdo\Sqlite::createAggregate — Registers an aggregating user-defined function for use in SQL statements
$name,$step,$finalize,$numArgs = -1This method is similar to Pdo\Sqlite::createFunction() except that it registers functions that can be used to calculate a result aggregated across all the rows of a query.
The key difference between this method and Pdo\Sqlite::createFunction() is that two functions are required to manage the aggregate.
By using this method it is possible to override native SQL functions.
namestepThis function need to be defined as:
contextnull for the first row; on subsequent rows it will have the value
that was previously returned from the step function; you should use
this to maintain the aggregate state.
rownumbervaluevaluescontext argument in the next call of the step or
finalize functions.
finalizeThis function need to be defined as:
contextHolds the return value from the very last call to the step function.
rowcountHolds the number of rows over which the aggregate was performed.
numArgsExample #1 Pdo\Sqlite::createAggregate() example
In this example we will create a custom aggregate function named
max_length that can be used in SQL queries.
In this example, we are creating an aggregating function,
named max_length, that will calculate the length
of the longest string in one of the columns of the table.
For each row, the max_len_step function is called and
passed a $context parameter.
The context parameter is just like any other PHP variable and be set to
hold an array or even an object .
In this example, we are using it to hold the maximum length we have seen so far;
if the $string has a length longer than the current maximum,
we update the context to hold this new maximum length.
After all the rows have been processed,
SQLite calls the max_len_finalize function to determine
the aggregate result.
It is possible to perform some kind of calculation based on the data in $context.
In this basic example the result was calculated as the query progressed,
thus so the context value can be directly returned.
<?php
$data = [
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
];
$db = new Pdo\Sqlite('sqlite::memory:');
$db->exec("CREATE TABLE strings(a)");
$insert = $db->prepare('INSERT INTO strings VALUES (?)');
foreach ($data as $str) {
$insert->execute(array($str));
}
$insert = null;
function max_len_step($context, $row_number, $string)
{
if (strlen($string) > $context) {
$context = strlen($string);
}
return $context;
}
function max_len_finalize($context, $row_count)
{
return $context === null ? 0 : $context;
}
$db->createAggregate('max_len', 'max_len_step', 'max_len_finalize');
var_dump($db->query('SELECT max_len(a) from strings')->fetchAll());
?>It is NOT recommended for you to store a copy of the values in the context and then process them at the end, as you would cause SQLite to use a lot of memory to process the query - just think of how much memory you would need if a million rows were stored in memory, each containing a string 32 bytes in length.