Sorting column must appear in the GROUP BY clause
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
add a comment |
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
I am surely missing something, but the problem as it is stated has an obvious solutionfrom(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
add a comment |
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
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
elixir phoenix-framework ecto
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 solutionfrom(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
add a comment |
I am surely missing something, but the problem as it is stated has an obvious solutionfrom(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
add a comment |
1 Answer
1
active
oldest
votes
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 Stop
s in case different Bus
es have same Stop
s. 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 Stop
s, you need to do a from(s in Stop)
.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 Stop
s in case different Bus
es have same Stop
s. 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 Stop
s, you need to do a from(s in Stop)
.
add a comment |
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 Stop
s in case different Bus
es have same Stop
s. 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 Stop
s, you need to do a from(s in Stop)
.
add a comment |
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 Stop
s in case different Bus
es have same Stop
s. 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 Stop
s, you need to do a from(s in Stop)
.
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 Stop
s in case different Bus
es have same Stop
s. 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 Stop
s, you need to do a from(s in Stop)
.
answered Nov 22 '18 at 9:29
Rahul SharmaRahul Sharma
459618
459618
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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