{"action":"opened","issue":{"url":"https://api.github.com/repos/elixir-ecto/ecto/issues/1849","repository_url":"https://api.github.com/repos/elixir-ecto/ecto","labels_url":"https://api.github.com/repos/elixir-ecto/ecto/issues/1849/labels{/name}","comments_url":"https://api.github.com/repos/elixir-ecto/ecto/issues/1849/comments","events_url":"https://api.github.com/repos/elixir-ecto/ecto/issues/1849/events","html_url":"https://github.com/elixir-ecto/ecto/issues/1849","id":195020521,"number":1849,"title":"Allowing for multiple selects in a query","user":{"login":"jeregrine","id":100886,"avatar_url":"https://avatars.githubusercontent.com/u/100886?v=3","gravatar_id":"","url":"https://api.github.com/users/jeregrine","html_url":"https://github.com/jeregrine","followers_url":"https://api.github.com/users/jeregrine/followers","following_url":"https://api.github.com/users/jeregrine/following{/other_user}","gists_url":"https://api.github.com/users/jeregrine/gists{/gist_id}","starred_url":"https://api.github.com/users/jeregrine/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/jeregrine/subscriptions","organizations_url":"https://api.github.com/users/jeregrine/orgs","repos_url":"https://api.github.com/users/jeregrine/repos","events_url":"https://api.github.com/users/jeregrine/events{/privacy}","received_events_url":"https://api.github.com/users/jeregrine/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2016-12-12T16:32:32Z","updated_at":"2016-12-12T16:32:32Z","closed_at":null,"body":"Problem\r\n\r\nWhen building queries that compose you can append `where` clauses and `limits`, but you can only have one `select` clause defined per query. This causes duplication when building queries that need to append additional values that are not defined in the original schema. \r\n\r\nThis is problem we've experienced when building API's that require complex query results.  Below is a simplified example that, while a bit contrived, represents a real life example. \r\n\r\nExample\r\n\r\n```elixir\r\ndef summary(query, :average) do\r\n  from v in query, \r\n    select: %{\r\n       total_count: fragment(\"count(?) as total_count\", v.id),\r\n       value: average(v.runtime)\r\n    }\r\nend\r\n\r\ndef summary(query, :sum) do\r\n  from v in query, \r\n    select: %{\r\n       total_count: fragment(\"count(?) as total_count\", v.id),\r\n       value: sum(v.runtime)\r\n    }\r\nend\r\n\r\ndef summary(query, :median) do\r\n  from v in query, \r\n    select: %{\r\n       total_count: fragment(\"count(?) as total_count\", v.id),\r\n       value: fragment(\"quantile(?, 0.5) as value\", v.time)\r\n    }\r\nend\r\n```\r\n... continued for multiple summary style stats. Each with a similar structure, but small differences. \r\n\r\nNow if we want to rename total_count we'll need to do it in 3 different places. \r\n\r\nProposal\r\n\r\nAn addition to the Ecto query API called `select_merge` this will take the existing select map|dict|list and merge it with the one supplied to `select_merge` overwriting keys in the new map, if no select is currently defined it will use the value as is. Much like the Dict.merge semantics. \r\n\r\nExample\r\n```elixir\r\ndef summary_common(query) do\r\n  from v in query,\r\n    select_merge: %{ \r\n      total_count: fragment(\"count(?) as total_count\", v.id)\r\n    }\r\nend\r\n\r\ndef summary(query, :average) do\r\n   from(v in query, \r\n     select: %{\r\n        value:  average(v.runtime)\r\n     })\r\n   |> summary_common()\r\nend\r\n ...\r\n```\r\n\r\nIn my ideal world `select` would always merge if it encounters multiple select's but I think this is a safer way. \r\n\r\nI do not have a strong understanding about how this will change aggregates, groupings, subqueries or joins. \r\n\r\nFurther Discussion from the Mailing List: https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/elixir-ecto/ymyULSUhPnk/ruDdtk5nBQAJ\r\n\r\n"}}
{"actor":{"display_login":"jeregrine"}}