Converting SQL to Arel - column […] must appear in the GROUP BY clause
I have a working SQL query and I would like to convert it into an Arel, but I seem to keep on running into the same error.
Working SQL:
Order.find_by_sql(
"SELECT COUNT(order_number) AS order_count,
restaurant_id, date_part('month', date) AS date_month,
date_part('year', date) AS date_year
FROM orders
WHERE restaurant_id is not null
GROUP BY(restaurant_id, date_part('month', date), date_part('year', date))
ORDER BY date_part('year', date) desc, date_part('month', date) desc;"
)
Attempt 1 (not working)
orders = Order.arel_table
Order
.where.not(restaurant_id: nil)
.select(:restaurant_id)
.select(:date)
.select(Order.arel_table[:order_number].count.as('order_count'))
.select(
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), :date]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.group(
:restaurant_id,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
Attempt 2 (not working)
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(orders[:date].desc)
.to_sql
Order.find_by_sql(query)
Both approaches result in the following error:
PG::GroupingError: ERROR: column "orders.date" must appear in the GROUP BY clause or be used in an aggregate function
The problem is that I don't want to group by date, but by month. Any tips on how to solve it?
I also originally tried Arel::Nodes::NamedFunction.new('date_part', ['month', :date]) instead of Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]) but it resulted with the following:
Unsupported argument type: String. Construct an Arel node instead.
Any help greatly appreciated. Thanks!
postgresql arel
add a comment |
I have a working SQL query and I would like to convert it into an Arel, but I seem to keep on running into the same error.
Working SQL:
Order.find_by_sql(
"SELECT COUNT(order_number) AS order_count,
restaurant_id, date_part('month', date) AS date_month,
date_part('year', date) AS date_year
FROM orders
WHERE restaurant_id is not null
GROUP BY(restaurant_id, date_part('month', date), date_part('year', date))
ORDER BY date_part('year', date) desc, date_part('month', date) desc;"
)
Attempt 1 (not working)
orders = Order.arel_table
Order
.where.not(restaurant_id: nil)
.select(:restaurant_id)
.select(:date)
.select(Order.arel_table[:order_number].count.as('order_count'))
.select(
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), :date]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.group(
:restaurant_id,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
Attempt 2 (not working)
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(orders[:date].desc)
.to_sql
Order.find_by_sql(query)
Both approaches result in the following error:
PG::GroupingError: ERROR: column "orders.date" must appear in the GROUP BY clause or be used in an aggregate function
The problem is that I don't want to group by date, but by month. Any tips on how to solve it?
I also originally tried Arel::Nodes::NamedFunction.new('date_part', ['month', :date]) instead of Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]) but it resulted with the following:
Unsupported argument type: String. Construct an Arel node instead.
Any help greatly appreciated. Thanks!
postgresql arel
add a comment |
I have a working SQL query and I would like to convert it into an Arel, but I seem to keep on running into the same error.
Working SQL:
Order.find_by_sql(
"SELECT COUNT(order_number) AS order_count,
restaurant_id, date_part('month', date) AS date_month,
date_part('year', date) AS date_year
FROM orders
WHERE restaurant_id is not null
GROUP BY(restaurant_id, date_part('month', date), date_part('year', date))
ORDER BY date_part('year', date) desc, date_part('month', date) desc;"
)
Attempt 1 (not working)
orders = Order.arel_table
Order
.where.not(restaurant_id: nil)
.select(:restaurant_id)
.select(:date)
.select(Order.arel_table[:order_number].count.as('order_count'))
.select(
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), :date]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.group(
:restaurant_id,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
Attempt 2 (not working)
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(orders[:date].desc)
.to_sql
Order.find_by_sql(query)
Both approaches result in the following error:
PG::GroupingError: ERROR: column "orders.date" must appear in the GROUP BY clause or be used in an aggregate function
The problem is that I don't want to group by date, but by month. Any tips on how to solve it?
I also originally tried Arel::Nodes::NamedFunction.new('date_part', ['month', :date]) instead of Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]) but it resulted with the following:
Unsupported argument type: String. Construct an Arel node instead.
Any help greatly appreciated. Thanks!
postgresql arel
I have a working SQL query and I would like to convert it into an Arel, but I seem to keep on running into the same error.
Working SQL:
Order.find_by_sql(
"SELECT COUNT(order_number) AS order_count,
restaurant_id, date_part('month', date) AS date_month,
date_part('year', date) AS date_year
FROM orders
WHERE restaurant_id is not null
GROUP BY(restaurant_id, date_part('month', date), date_part('year', date))
ORDER BY date_part('year', date) desc, date_part('month', date) desc;"
)
Attempt 1 (not working)
orders = Order.arel_table
Order
.where.not(restaurant_id: nil)
.select(:restaurant_id)
.select(:date)
.select(Order.arel_table[:order_number].count.as('order_count'))
.select(
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), :date]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.group(
:restaurant_id,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
Attempt 2 (not working)
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(orders[:date].desc)
.to_sql
Order.find_by_sql(query)
Both approaches result in the following error:
PG::GroupingError: ERROR: column "orders.date" must appear in the GROUP BY clause or be used in an aggregate function
The problem is that I don't want to group by date, but by month. Any tips on how to solve it?
I also originally tried Arel::Nodes::NamedFunction.new('date_part', ['month', :date]) instead of Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]) but it resulted with the following:
Unsupported argument type: String. Construct an Arel node instead.
Any help greatly appreciated. Thanks!
postgresql arel
postgresql arel
asked Nov 26 '18 at 8:48
Joanna GaudynJoanna Gaudyn
252113
252113
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
So after hours of digging it turns out the big gotcha! of my problem was a default_scope set on my Order model - that's where sorting by :date was happening. In the end I decided to remove the default scope, use sorting where it was actually needed and what I was left it regarding my query was this:
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), date]).desc,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), date]).desc
)
.to_sql
Order.find_by_sql(query)
Lesson learnt: avoid default_scopes whenever possible. If you work alone, you're likely to forget you used it over time. If you work in a team, you might just cost somebody a full day of hair pulling.
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%2f53477446%2fconverting-sql-to-arel-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
So after hours of digging it turns out the big gotcha! of my problem was a default_scope set on my Order model - that's where sorting by :date was happening. In the end I decided to remove the default scope, use sorting where it was actually needed and what I was left it regarding my query was this:
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), date]).desc,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), date]).desc
)
.to_sql
Order.find_by_sql(query)
Lesson learnt: avoid default_scopes whenever possible. If you work alone, you're likely to forget you used it over time. If you work in a team, you might just cost somebody a full day of hair pulling.
add a comment |
So after hours of digging it turns out the big gotcha! of my problem was a default_scope set on my Order model - that's where sorting by :date was happening. In the end I decided to remove the default scope, use sorting where it was actually needed and what I was left it regarding my query was this:
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), date]).desc,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), date]).desc
)
.to_sql
Order.find_by_sql(query)
Lesson learnt: avoid default_scopes whenever possible. If you work alone, you're likely to forget you used it over time. If you work in a team, you might just cost somebody a full day of hair pulling.
add a comment |
So after hours of digging it turns out the big gotcha! of my problem was a default_scope set on my Order model - that's where sorting by :date was happening. In the end I decided to remove the default scope, use sorting where it was actually needed and what I was left it regarding my query was this:
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), date]).desc,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), date]).desc
)
.to_sql
Order.find_by_sql(query)
Lesson learnt: avoid default_scopes whenever possible. If you work alone, you're likely to forget you used it over time. If you work in a team, you might just cost somebody a full day of hair pulling.
So after hours of digging it turns out the big gotcha! of my problem was a default_scope set on my Order model - that's where sorting by :date was happening. In the end I decided to remove the default scope, use sorting where it was actually needed and what I was left it regarding my query was this:
orders = Order.arel_table
query = orders
.where(orders[:restaurant_id].not_eq(nil))
.project(
orders[:restaurant_id],
Order.arel_table[:order_number].count.as('order_count'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]).as('date_month'),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]]).as('date_year'),
)
.group(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), orders[:date]]),
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), orders[:date]])
)
.order(
orders[:restaurant_id],
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('year'), date]).desc,
Arel::Nodes::NamedFunction.new('date_part', [Arel::Nodes.build_quoted('month'), date]).desc
)
.to_sql
Order.find_by_sql(query)
Lesson learnt: avoid default_scopes whenever possible. If you work alone, you're likely to forget you used it over time. If you work in a team, you might just cost somebody a full day of hair pulling.
answered Nov 27 '18 at 8:34
Joanna GaudynJoanna Gaudyn
252113
252113
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%2f53477446%2fconverting-sql-to-arel-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