DBICの集約関数
http://www.ornithopter.jp/archives/2006/11/dbixclassdbic_d_1.html
ケースによってはもっとスマートに扱えます。
こんな感じのデータがあったとします。
> select * from item; +----+------------+------+-------+---------------------+---------------------+ | id | rid | name | price | created_on | timestamp | +----+------------+------+-------+---------------------+---------------------+ | 1 | tkVjn4E2cQ | pen | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 2 | DN2mdgPzIv | note | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 3 | UBCzoZKGES | clip | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | +----+------------+------+-------+---------------------+---------------------+ 3 rows in set (0.00 sec) > select * from order_log; +----+------------+---------+-------+---------------------+---------------------+ | id | rid | item_id | price | created_on | timestamp | +----+------------+---------+-------+---------------------+---------------------+ | 1 | UFmfRbLqhb | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 2 | uQpIOMYUAI | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 3 | BygAzHR1Yy | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 4 | yjRWqnha7M | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 5 | NS2Ozw4KxQ | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 6 | bf0Q5eUi4J | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 7 | VWM9BqVpVt | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 8 | oeAvPeoJC7 | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 9 | pDWrqE76EM | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 10 | hB0OC6Gr0J | 1 | 500 | 2007-02-17 13:55:06 | 2007-02-17 13:55:06 | | 11 | bRCs0jNTkc | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 12 | 8kmAxd6WMX | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 13 | unKf9Ev55M | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 14 | 4S0klustrh | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 15 | ERuaDrgUEq | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 16 | InxEbt1WY3 | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 17 | OZeIim9NNn | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 18 | 7Rm21QIKty | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 19 | CivnxL9d9X | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 20 | 28WbYvoOc0 | 2 | 600 | 2007-02-17 13:55:39 | 2007-02-17 13:55:39 | | 21 | o2LngQVTnE | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 22 | 8JZxq7XcvC | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 23 | ya1G5atTlt | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 24 | U7DaqFgbDs | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 25 | TB4tnp0fua | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 26 | avhNCX65Yq | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 27 | tthExVsWcp | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 28 | BeB8NNjlaj | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 29 | nLhTCnh50X | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | | 30 | ScxXW7SeM3 | 3 | 100 | 2007-02-17 13:55:58 | 2007-02-17 13:55:58 | +----+------------+---------+-------+---------------------+---------------------+
ここでpenの売り上げ合計を確認したい場合、
my $rs = $schema->resultset('OrderLog')->search( { 'item_id.name' => 'pen', }, { join => 'item_id', } ); warn $rs->get_column('me.price')->sum;
これだけで十分。
もちろん、カウントとったりしたい場合とかは複数回クエリーが投げられることになり、
1クエリで全ては処理できませんが。
実行されるSQL
Executing : SELECT SUM( me.price ) FROM order_log me JOIN item item_id ON ( item_id.id = me.item_id ) WHERE ( item_id.name = ? ) ORDER BY me.id DESC : 'pen' -->Query Time: 0.001746. -->ALL Query Time: 0.001746 --------------------------------------------------------------------------------- 5000 at /...
DBICは集合関数を結構賢くさばいてくれます。
他にもmin、maxとかも。
実際はminもmaxもsumもfuncメソッドへのラッパーなだけなので、
他にも色々できるます。
funcメソッドはこんなの。
sub func { my $self = shift; my $function = shift; my ($row) = $self->{_parent_resultset}->search(undef, {select => {$function => $self->{_column}}, as => [$self->{_column}]})->cursor->next; return $row; }