Sorting column must appear in the GROUP BY clause











up vote
0
down vote

favorite












I'm using a postgresql database in my phoenix application. I have a table of buses, each of which is associated with one or more stops and routes. I'm trying to make a searchable list of all stops, but I don't want to re-write my searching and filtering functions (see list_filtered_buses).



So, in sort_bus_list, I'm trying to return a sorted list of all stops.
My issue with the current implementation is that I get back duplicates when I render the list in my template since each bus is being returned with all its stops. I've tried two different approaches, one returning duplicates, and one preventing sorting due to an error.



Here is relevant code in sort_bus_list in buses.ex:



  # V1 - sortable, but returns duplicates
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], [s.id, b.id])

# V2 - doesn't return duplicates, but isn't returns error:
# ERROR 42803 (grouping_error): column "b1.stop_id" must appear in the GROUP BY clause or be used in an aggregate function
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], b.id)


Here's pseudo-code of my template:



for bus in Buses
for stop in bus
display stop
end
end


More buses.ex code for context:



 def list_filtered_buses(params) do
search_term = params["filter"]["query"]

from(t in Bus, join: a in assoc(t, :stops), join: c in assoc(t, :routes))
|> search(search_term)
|> list_buses_by_active(params)
|> list_buses_by_type(params)
|> sort_buses_list(params)
|> preload([:stops, :routes])
end


def sort_bus_list(list, params) do
attrs = process_sorting_metrics(params)

case params["filter"]["sort_attr"] do
a when a == "stop_name" or a == "stop_id" ->

#V2 - sortable, but returns duplcate
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], [s.id, b.id])

"route_name" ->
list
|> order_by([b, s, r], {^attrs.sort_dir, field(r, ^attrs.sort_attr)})
|> group_by([b, s, r], [b.id, r.id])

_ ->
list
|> order_by([b, s, r], {^attrs.sort_dir, field(b, ^attrs.sort_attr)})
|> group_by([b, s, r], b.id)
end
end









share|improve this question
























  • I am surely missing something, but the problem as it is stated has an obvious solution from(s in Stop).
    – Aleksei Matiushkin
    Nov 22 at 4:47










  • Welcome to SO! I think the problem lies with the way you're structuring your query in general. See this. If that doesn't help, try rephrasing your question, focusing on the core problem.
    – Sheharyar
    Nov 22 at 12:21















up vote
0
down vote

favorite












I'm using a postgresql database in my phoenix application. I have a table of buses, each of which is associated with one or more stops and routes. I'm trying to make a searchable list of all stops, but I don't want to re-write my searching and filtering functions (see list_filtered_buses).



So, in sort_bus_list, I'm trying to return a sorted list of all stops.
My issue with the current implementation is that I get back duplicates when I render the list in my template since each bus is being returned with all its stops. I've tried two different approaches, one returning duplicates, and one preventing sorting due to an error.



Here is relevant code in sort_bus_list in buses.ex:



  # V1 - sortable, but returns duplicates
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], [s.id, b.id])

# V2 - doesn't return duplicates, but isn't returns error:
# ERROR 42803 (grouping_error): column "b1.stop_id" must appear in the GROUP BY clause or be used in an aggregate function
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], b.id)


Here's pseudo-code of my template:



for bus in Buses
for stop in bus
display stop
end
end


More buses.ex code for context:



 def list_filtered_buses(params) do
search_term = params["filter"]["query"]

from(t in Bus, join: a in assoc(t, :stops), join: c in assoc(t, :routes))
|> search(search_term)
|> list_buses_by_active(params)
|> list_buses_by_type(params)
|> sort_buses_list(params)
|> preload([:stops, :routes])
end


def sort_bus_list(list, params) do
attrs = process_sorting_metrics(params)

case params["filter"]["sort_attr"] do
a when a == "stop_name" or a == "stop_id" ->

#V2 - sortable, but returns duplcate
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], [s.id, b.id])

"route_name" ->
list
|> order_by([b, s, r], {^attrs.sort_dir, field(r, ^attrs.sort_attr)})
|> group_by([b, s, r], [b.id, r.id])

_ ->
list
|> order_by([b, s, r], {^attrs.sort_dir, field(b, ^attrs.sort_attr)})
|> group_by([b, s, r], b.id)
end
end









share|improve this question
























  • I am surely missing something, but the problem as it is stated has an obvious solution from(s in Stop).
    – Aleksei Matiushkin
    Nov 22 at 4:47










  • Welcome to SO! I think the problem lies with the way you're structuring your query in general. See this. If that doesn't help, try rephrasing your question, focusing on the core problem.
    – Sheharyar
    Nov 22 at 12:21













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I'm using a postgresql database in my phoenix application. I have a table of buses, each of which is associated with one or more stops and routes. I'm trying to make a searchable list of all stops, but I don't want to re-write my searching and filtering functions (see list_filtered_buses).



So, in sort_bus_list, I'm trying to return a sorted list of all stops.
My issue with the current implementation is that I get back duplicates when I render the list in my template since each bus is being returned with all its stops. I've tried two different approaches, one returning duplicates, and one preventing sorting due to an error.



Here is relevant code in sort_bus_list in buses.ex:



  # V1 - sortable, but returns duplicates
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], [s.id, b.id])

# V2 - doesn't return duplicates, but isn't returns error:
# ERROR 42803 (grouping_error): column "b1.stop_id" must appear in the GROUP BY clause or be used in an aggregate function
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], b.id)


Here's pseudo-code of my template:



for bus in Buses
for stop in bus
display stop
end
end


More buses.ex code for context:



 def list_filtered_buses(params) do
search_term = params["filter"]["query"]

from(t in Bus, join: a in assoc(t, :stops), join: c in assoc(t, :routes))
|> search(search_term)
|> list_buses_by_active(params)
|> list_buses_by_type(params)
|> sort_buses_list(params)
|> preload([:stops, :routes])
end


def sort_bus_list(list, params) do
attrs = process_sorting_metrics(params)

case params["filter"]["sort_attr"] do
a when a == "stop_name" or a == "stop_id" ->

#V2 - sortable, but returns duplcate
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], [s.id, b.id])

"route_name" ->
list
|> order_by([b, s, r], {^attrs.sort_dir, field(r, ^attrs.sort_attr)})
|> group_by([b, s, r], [b.id, r.id])

_ ->
list
|> order_by([b, s, r], {^attrs.sort_dir, field(b, ^attrs.sort_attr)})
|> group_by([b, s, r], b.id)
end
end









share|improve this question















I'm using a postgresql database in my phoenix application. I have a table of buses, each of which is associated with one or more stops and routes. I'm trying to make a searchable list of all stops, but I don't want to re-write my searching and filtering functions (see list_filtered_buses).



So, in sort_bus_list, I'm trying to return a sorted list of all stops.
My issue with the current implementation is that I get back duplicates when I render the list in my template since each bus is being returned with all its stops. I've tried two different approaches, one returning duplicates, and one preventing sorting due to an error.



Here is relevant code in sort_bus_list in buses.ex:



  # V1 - sortable, but returns duplicates
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], [s.id, b.id])

# V2 - doesn't return duplicates, but isn't returns error:
# ERROR 42803 (grouping_error): column "b1.stop_id" must appear in the GROUP BY clause or be used in an aggregate function
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], b.id)


Here's pseudo-code of my template:



for bus in Buses
for stop in bus
display stop
end
end


More buses.ex code for context:



 def list_filtered_buses(params) do
search_term = params["filter"]["query"]

from(t in Bus, join: a in assoc(t, :stops), join: c in assoc(t, :routes))
|> search(search_term)
|> list_buses_by_active(params)
|> list_buses_by_type(params)
|> sort_buses_list(params)
|> preload([:stops, :routes])
end


def sort_bus_list(list, params) do
attrs = process_sorting_metrics(params)

case params["filter"]["sort_attr"] do
a when a == "stop_name" or a == "stop_id" ->

#V2 - sortable, but returns duplcate
list
|> order_by([b, s, r], {^attrs.sort_dir, field(s, ^attrs.sort_attr)})
|> group_by([b, s, r], [s.id, b.id])

"route_name" ->
list
|> order_by([b, s, r], {^attrs.sort_dir, field(r, ^attrs.sort_attr)})
|> group_by([b, s, r], [b.id, r.id])

_ ->
list
|> order_by([b, s, r], {^attrs.sort_dir, field(b, ^attrs.sort_attr)})
|> group_by([b, s, r], b.id)
end
end






elixir phoenix-framework ecto






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 22 at 12:17









Sheharyar

43.4k10106158




43.4k10106158










asked Nov 21 at 17:54









Toni K.

282




282












  • I am surely missing something, but the problem as it is stated has an obvious solution from(s in Stop).
    – Aleksei Matiushkin
    Nov 22 at 4:47










  • Welcome to SO! I think the problem lies with the way you're structuring your query in general. See this. If that doesn't help, try rephrasing your question, focusing on the core problem.
    – Sheharyar
    Nov 22 at 12:21


















  • I am surely missing something, but the problem as it is stated has an obvious solution from(s in Stop).
    – Aleksei Matiushkin
    Nov 22 at 4:47










  • Welcome to SO! I think the problem lies with the way you're structuring your query in general. See this. If that doesn't help, try rephrasing your question, focusing on the core problem.
    – Sheharyar
    Nov 22 at 12:21
















I am surely missing something, but the problem as it is stated has an obvious solution from(s in Stop).
– Aleksei Matiushkin
Nov 22 at 4:47




I am surely missing something, but the problem as it is stated has an obvious solution from(s in Stop).
– Aleksei Matiushkin
Nov 22 at 4:47












Welcome to SO! I think the problem lies with the way you're structuring your query in general. See this. If that doesn't help, try rephrasing your question, focusing on the core problem.
– Sheharyar
Nov 22 at 12:21




Welcome to SO! I think the problem lies with the way you're structuring your query in general. See this. If that doesn't help, try rephrasing your question, focusing on the core problem.
– Sheharyar
Nov 22 at 12:21












1 Answer
1






active

oldest

votes

















up vote
1
down vote



accepted










As it seems, you're trying to render only Stop. In the list_filtered_buses function, you're running a query on Bus table. Then, further you're trying to sort and group the data. The #V1 function is doing a group on Bus.id and Stop.id so you get duplicate Stops in case different Buses have same Stops. The #V2 function however returns error because you're doing a select query on Bus and you're doing group only on Bus.id and trying to render attributes from Stop.



As @AlekseiMatiushkin suggested, in order to render only distinct Stops, you need to do a from(s in Stop).






share|improve this answer





















    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53417962%2fsorting-column-must-appear-in-the-group-by-clause%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    1 Answer
    1






    active

    oldest

    votes








    1 Answer
    1






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    1
    down vote



    accepted










    As it seems, you're trying to render only Stop. In the list_filtered_buses function, you're running a query on Bus table. Then, further you're trying to sort and group the data. The #V1 function is doing a group on Bus.id and Stop.id so you get duplicate Stops in case different Buses have same Stops. The #V2 function however returns error because you're doing a select query on Bus and you're doing group only on Bus.id and trying to render attributes from Stop.



    As @AlekseiMatiushkin suggested, in order to render only distinct Stops, you need to do a from(s in Stop).






    share|improve this answer

























      up vote
      1
      down vote



      accepted










      As it seems, you're trying to render only Stop. In the list_filtered_buses function, you're running a query on Bus table. Then, further you're trying to sort and group the data. The #V1 function is doing a group on Bus.id and Stop.id so you get duplicate Stops in case different Buses have same Stops. The #V2 function however returns error because you're doing a select query on Bus and you're doing group only on Bus.id and trying to render attributes from Stop.



      As @AlekseiMatiushkin suggested, in order to render only distinct Stops, you need to do a from(s in Stop).






      share|improve this answer























        up vote
        1
        down vote



        accepted







        up vote
        1
        down vote



        accepted






        As it seems, you're trying to render only Stop. In the list_filtered_buses function, you're running a query on Bus table. Then, further you're trying to sort and group the data. The #V1 function is doing a group on Bus.id and Stop.id so you get duplicate Stops in case different Buses have same Stops. The #V2 function however returns error because you're doing a select query on Bus and you're doing group only on Bus.id and trying to render attributes from Stop.



        As @AlekseiMatiushkin suggested, in order to render only distinct Stops, you need to do a from(s in Stop).






        share|improve this answer












        As it seems, you're trying to render only Stop. In the list_filtered_buses function, you're running a query on Bus table. Then, further you're trying to sort and group the data. The #V1 function is doing a group on Bus.id and Stop.id so you get duplicate Stops in case different Buses have same Stops. The #V2 function however returns error because you're doing a select query on Bus and you're doing group only on Bus.id and trying to render attributes from Stop.



        As @AlekseiMatiushkin suggested, in order to render only distinct Stops, you need to do a from(s in Stop).







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 22 at 9:29









        Rahul Sharma

        449617




        449617






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.





            Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


            Please pay close attention to the following guidance:


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53417962%2fsorting-column-must-appear-in-the-group-by-clause%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Berounka

            Sphinx de Gizeh

            Different font size/position of beamer's navigation symbols template's content depending on regular/plain...