selected_fields = [:inbox_count, :phone_number_count, :comment_count, ...] #this list contains fields of a table, and can change by the needed
group_query =
from(
ps in PageStatistic,
where: ps.id in ['1', '2']
group_by: fragment("date(?)", ps.hour)
select: %{
day: fragment("date(?)", ps.hour),
}
final_query =
select_fields
|> Enum.reduce(group_query, fn field, query ->
field_string = to_string(field)
select_merge(query, [ps], %{^field_string => fragment("sum(?)", field(ps, ^field))})
)
Repo.all(final_query)
but i got result like this
[
%{
:day => ~D[2023-01-01],
"inbox_count" => 3,
...
},
...
]
Is there any way make key “inbox_count” is an atom same as :day when query(i don’t want to loop the result to convert string to atom)
And is there any solution to select sum all fields that exist in select_fields when i make a query to database
You’re explicitly calling field_string = to_string(field) so that’s why you’re getting a string. I don’t see any reason you need to do this so just remove that line.
I’m missing something why you do need it or if you are ever in a situation where you have a string you don’t control and want it as an atom, you can write it like this:
thank you for response, reason why i need convert field to field_string is that if the query when i bind atom to field need select, will like this (you can notice new_customer_count and other field need sum)
** (DBConnection.EncodeError) Postgrex expected a binary, got :new_customer_count. Please make sure the value you are passing matches the definition in your table or in your query or convert the value accordingly.
That sounds more like the value of the field you are trying to select into is the wrong type, although you are returning a bare map so that shouldn’t matter
I am, however, realizing that I mistakingly read Ecto 3.0 as 3.10, so that likely has something to do with it because I can’t for the life of me reproduce this in 3.11. Very sorry about that