(PHP 8 >= 8.4.0)
Pdo\Sqlite::createAggregate — SQL 文で使用するユーザー定義集約関数を登録する
$name
,$step
,$finalize
,$numArgs
= -1このメソッドは Pdo\Sqlite::createFunction() と似ていますが、クエリのすべての行を集約する関数を登録する点が 異なります。
この関数と Pdo\Sqlite::createFunction() の最大の違いは、集約関数の登録には 2 つの関数が必要であるということです。
このメソッドを使用してネイティブ SQL 関数を上書きすることができます。
name
step
定義は次のとおりです:
context
null
2行目以降では、この関数が前回返した値です。
この値で集約の状態を管理します。
rownumber
value
values
context
引数として
使います。
finalize
定義は次のとおりです:
context
ステップ関数の最後の戻り値
rowcount
ステップ関数が処理した行数
numArgs
例1 Pdo\Sqlite::createAggregate() example
この例では、SQLクエリの中で使用できる
max_length
という名前のユーザー定義集約関数を作成しています。
この例では、max_length
という集約関数を
作成しています。この関数はテーブルの特定のカラム内で
最も長い文字列の長さを計算します。
各行に対し max_len_step
関数が呼ばれ、
その際に $context
パラメータが渡されます。
この context パラメータには、他の PHP 変数と同様
array や object などを格納できます。
この例では、これまでの中で最大の文字列長を格納するために利用しています。
もし $string が現在の最大値よりも長ければ、
context に格納した最大長を新たな値で更新します。
全ての行が処理された後、
SQLite は集約関数の結果を計算するため max_len_finalize
関数を呼び出します。
$context
内のデータに基づいて何らかの計算を行うことも可能です。
この例では、結果はクエリの進行中に計算されているため、
context の値をそのまま返すことができます。
<?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());
?>
結果の値を context に蓄積し、最後に一括で処理する方法は推奨 「しません」。これは、SQLite のメモリ消費量が大きくなるからです。 仮に 32 バイトの長さのデータが百万件あったとして、 それを蓄積しておくのにどれだけのメモリが必要になるか 考えてみましょう。