So, I have a query that I'm trying to construct where there's a list attributes
which are columns on a table. This query is to group by the list of attributes, count, and return the count with the list of attributes. That last part is what I've had the trouble achieving. Right now I have
defmodule ProjectName.Counter do
import Ecto.Query, only: [group_by: 3, select: 3]
def group_and_count(queryable, groups) do
queryable
|> group_by([q], ^groups)
|> select([q], count(q.id))
end
end
Which I invoke as such in a context
Track
|> Counter.group_and_count([:album, :artist])
|> Repo.all()
Which returns me [1, 5, 4, 2]
which is correct however, not what I'd like it to return. I'd like to actually have the query
SELECT COUNT(*), tracks.album, tracks.artist FROM tracks GROUP BY tracks.album, tracks.artist
which would return
[[1, "Calypso", "Harry Belafonte"],
[5, "Silk & Soul", "Nina Simone"],
[4, "Hello, Dolly!", "Louis Armstrong"],
[2, "Pure Gold", "Perry Como"]]
How can I change my code to make this work? I can't figure out a way to iterate over groups
within the select
query.
There's probably a much better way of doing it, but it looks like map/2 and struct/2 are made to support passing in lists.
It's ugly, but you could just select
a tuple containing a map and the count:
|> select([q], {map(q, ^groups), count(q.id)})