Sorting column must appear in the GROUP BY clause












0















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 '18 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 '18 at 12:21
















0















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 '18 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 '18 at 12:21














0












0








0








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 '18 at 12:17









Sheharyar

45k10107161




45k10107161










asked Nov 21 '18 at 17:54









Toni K.Toni K.

284




284













  • I am surely missing something, but the problem as it is stated has an obvious solution from(s in Stop).

    – Aleksei Matiushkin
    Nov 22 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 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 '18 at 12:21












1 Answer
1






active

oldest

votes


















1














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',
    autoActivateHeartbeat: false,
    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









    1














    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




























      1














      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


























        1












        1








        1







        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 '18 at 9:29









        Rahul SharmaRahul Sharma

        459618




        459618
































            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.




            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

            "Incorrect syntax near the keyword 'ON'. (on update cascade, on delete cascade,)

            Alcedinidae

            Origin of the phrase “under your belt”?