beam
beam copied to clipboard
Multicolumn aggregate
Hi,
I would like to have 3 aggregated columns. A query with 2 aggregate columns is defined as:
import Data.Bifunctor qualified as BF
import Database.Beam
import Database.Beam.Backend.SQL.BeamExtensions (runInsertReturningList)
import Database.Beam.Postgres
import Database.PostgreSQL.Simple
import Database.PostgreSQL.Simple.Types
userDataTableDigestQ :: UserTable -> SqlSelect
Postgres (UserDataTable, UserDataTable)
userDataTableDigestQ ut = select ag
where
al = all_ (userDataTableRef $ usertableName ut)
ag = subselect_ $ aggregate_
(BF.bimap group_ group_)
((,)
<$> limit_ 1 (orderBy_ (asc_ . userdatatableTs) al)
<*> limit_ 1 (orderBy_ (desc_ . userdatatableTs) al))
To get 3 column logical solution is to use trimap/Trifunctor, but there is no such function/class on hoogle, so I am worried that this might be wrong way to go.
Trifunctor works
class Trifunctor p where
trimap :: (a -> d) -> (b -> e) -> (c -> f) -> p a b c -> p d e f
instance Trifunctor (,,) where
trimap fa fb fc ~(a, b, c) = (fa a, fb b, fc c)
but group_ and countAll_ don't fit together even for 2 columns
userDataTableDigestQ3 :: UserTable -> SqlSelect
Postgres (UserTable, Int32)
userDataTableDigestQ3 ut = select ag
where
al = all_ (userDataTableRef $ usertableName ut)
ag = subselect_ $ aggregate_
(BF.bimap group_ (\_ -> as_ @Int32 countAll_))
((,)
<$> limit_ 1 (orderBy_ (asc_ . userdatatableTs) al)
<*> al)