[Dbix-class] best practices for sub-grouping results?
Darren Duncan
darren at darrenduncan.net
Tue Apr 1 10:12:16 BST 2008
Jason Gottshall wrote:
> Has anyone else found an elegant/efficient solution to this problem?
> I've been toying with the idea of creating some sort of DBIC::RSGrouped
> component to encapsulate this scenario, but I don't want to trudge too
> far down that road without some advice from the community!
How I would solve that problem is with an analogy to SQL's GROUP BY that
returns the grouped rows as groups of rows rather than just the results of
performing aggregate functions on said rows.
For example, given a table like this:
MYTBL
COL1|COL2
----+----
a | 1
----+----
a | 2
----+----
a | 3
----+----
b | 4
----+----
b | 5
I could say in quasi-SQL:
SELECT COL1, COL3 FROM MYTBL GROUP (COL2) AS COL3
and get:
COL1|COL3
----+-----
a |+----
||COL2
|+----
|| 1
|+----
|| 2
|+----
|| 3
|+----
----+-----
b |+----
||COL2
|+----
|| 4
|+----
|| 5
|+----
That result rendered in Perl as per DBI's array-of-hashrefs would look like:
[
{ COL1 => 'a',
COL3 => [
{ COL2 => 1 },
{ COL2 => 2 },
{ COL2 => 3 },
],
},
{ COL1 => 'b',
COL3 => [
{ COL2 => 4 },
{ COL2 => 5 },
],
},
]
And you could then iterate through that in TT or what have you without
exposing your model too badly, because that structure came out of a single
query, not multiple queries that had to be interleaved.
Therefore, perhaps how you would solve the problem with DBIx::Class is to
make its interface work as if SQL supported what I demonstrated, and then
do things naturally as a single search query. Eg if you were to make an
extension, I suggest making it provide that feature.
-- Darren Duncan
P.S. The feature I demonstrated also has the advantage of being lossless;
you could get the original rowset back from the grouped one like this (the
subquery is the original, the outer query is the inverse operation):
SELECT COL1, COL2 FROM (
SELECT COL1, COL3 FROM MYTBL GROUP (COL2) AS COL3
) UNGROUP COL3 AS (COL2)
More information about the DBIx-Class
mailing list