PG:GroupingError 只出现在制作中
PG:GroupingError only appearing on production
我有一个模型 "Playlist",其中 has_many 和 belongs_to 另一个模型 "User",通过中介模型 "PlaylistUser"。
我有代码,对于给定的播放列表 @playlist
,列出与 @playlist
共享一个用户的所有其他播放列表,按它们共享的数量排序。
此代码在开发中完美运行,但在生产中,它抛出此错误:
PG::GroupingError: ERROR: column "playlists.name" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT "playlists".* FROM "playlists" INNER JOIN "playlist...
^
: SELECT "playlists".* FROM "playlists" INNER JOIN "playlist_users" ON "playlist_users"."playlist_id" = "playlists"."id" INNER JOIN "users" ON "users"."id" = "playlist_users"."user_id" WHERE (NOT (playlists.id = 30 OR playlists.id = 41)) AND "users"."id" IN (45, 89, 71, 117, 115, 173, 177, 180, 161, 220, 223, 199, 221, 239, 204, 205, 206, 207, 211, 261, 282, 284, 286, 251, 252, 255, 310, 311, 315, 318, 307, 362, 319, 306, 289, 316, 305, 321, 322, 330, 333, 292, 294, 304, 300, 340, 341, 342, 343, 405, 406, 410, 408, 409, 407, 413, 416, 417, 418, 425, 427, 392, 401, 403, 445, 446, 449, 450, 379, 456, 451, 454, 459, 437, 442, 444, 496, 501, 518, 548, 549, 533, 553, 1112, 1113, 1459, 455, 348, 1458, 242, 1275, 151, 1890, 336, 203, 404, 166, 453, 114, 157, 285, 448, 447, 443, 550, 2167, 2168, 287, 320, 293, 65, 2098, 2097, 2099, 387, 3, 2175, 2170, 2174, 2182, 2171, 438, 2180, 2181, 2169, 2176, 347, 2429, 2177, 2445, 2178, 2447, 58, 2480, 390, 452, 554, 555, 313, 92, 275, 335, 428, 167, 302, 2173, 1538) GROUP BY playlists.id ORDER BY count(*) desc
为什么我的查询适用于开发而不适用于生产?
查询
@playlist_ids = @playlist.user_ids
@more_playlists = Playlist.joins(:users).where.not('playlists.id = ? OR playlists.id = ?', 30, 41).where(users: {id: @playlist_ids}).group('playlists.id').order('count(*) desc')
协会:
class Playlist < ActiveRecord::Base
has_many :playlist_users
has_many :users, :through => :playlist_users
end
class PlaylistUser < ActiveRecord::Base
belongs_to :playlist
belongs_to :user
end
class User < ActiveRecord::Base
has_many :playlist_users
has_many :playlists, :through => :playlist_users
end
更新
这很奇怪,我按照 trincot 的建议将 Playlist.name 添加到 GROUP BY 中:
@playlist_ids = @playlist.user_ids
Playlist.select('playlists.id, playlists.name')
.joins(:playlist_users)
.where('playlists.id NOT IN (30, 41)')
.where(playlist_users: {user_id: @playlist_ids})
.group('playlists.id, playlists.name')
.order('count(*) desc')
但是我得到了一个类似的错误,只是现在它告诉我必须在 GROUP BY 子句中包含 Playlist
属性 subject_id
:
PG::GroupingError: ERROR: column "playlists.subject_id" must appear in the GROUP BY clause or be used in an aggregate function
但我并没有在查询中的任何地方引用 subject_id
,甚至在页面的模型、控制器或视图中。那个专栏到底为什么要参与其中?
根据 PostgreSQL documentation 您的陈述无效:
When GROUP BY is present, it is not valid for the SELECT list expressions to refer to
ungrouped columns except within aggregate functions, since there would be more than one
possible value to return for an ungrouped column.
如果你说它在你的开发环境中工作,那一定意味着环境有另一个数据库引擎(版本)运行。
您应该使用这样的语句,其中 SELECT
子句中的字段列表与 GROUP BY
子句中给出的列表相同:
SELECT playlists.id, playlists.name, ...
FROM playlists
INNER JOIN playlist_users ON playlist_users.playlist_id = playlists.id
WHERE playlists.id NOT IN (30, 41)
AND playlist_users.user_id IN (your_long_list_comes_here)
GROUP BY playlists.id, playlists.name, ...
ORDER BY count(*) desc
请注意,您实际上不需要加入 users table 以获得您感兴趣的结果,因此我删除了它并替换了 [= 上的测试31=]user_id 相应地。此外,使用 IN
运算符可以更简洁地表达 playlists.id 上的条件。
对应的 Active Record 查询为:
Playlist.joins(:playlist_users)
.where('playlists.id NOT IN (30, 41)')
.where(playlist_users: {user_id: @playlist_ids})
.select('playlists.id, playlists.name')
.group('playlists.id, playlists.name')
.order('count(*) desc')
您必须在 select
和 group
参数中添加您需要的任何其他字段。
我有一个模型 "Playlist",其中 has_many 和 belongs_to 另一个模型 "User",通过中介模型 "PlaylistUser"。
我有代码,对于给定的播放列表 @playlist
,列出与 @playlist
共享一个用户的所有其他播放列表,按它们共享的数量排序。
此代码在开发中完美运行,但在生产中,它抛出此错误:
PG::GroupingError: ERROR: column "playlists.name" must appear in the GROUP BY clause or be used in an aggregate function
LINE 1: SELECT "playlists".* FROM "playlists" INNER JOIN "playlist...
^
: SELECT "playlists".* FROM "playlists" INNER JOIN "playlist_users" ON "playlist_users"."playlist_id" = "playlists"."id" INNER JOIN "users" ON "users"."id" = "playlist_users"."user_id" WHERE (NOT (playlists.id = 30 OR playlists.id = 41)) AND "users"."id" IN (45, 89, 71, 117, 115, 173, 177, 180, 161, 220, 223, 199, 221, 239, 204, 205, 206, 207, 211, 261, 282, 284, 286, 251, 252, 255, 310, 311, 315, 318, 307, 362, 319, 306, 289, 316, 305, 321, 322, 330, 333, 292, 294, 304, 300, 340, 341, 342, 343, 405, 406, 410, 408, 409, 407, 413, 416, 417, 418, 425, 427, 392, 401, 403, 445, 446, 449, 450, 379, 456, 451, 454, 459, 437, 442, 444, 496, 501, 518, 548, 549, 533, 553, 1112, 1113, 1459, 455, 348, 1458, 242, 1275, 151, 1890, 336, 203, 404, 166, 453, 114, 157, 285, 448, 447, 443, 550, 2167, 2168, 287, 320, 293, 65, 2098, 2097, 2099, 387, 3, 2175, 2170, 2174, 2182, 2171, 438, 2180, 2181, 2169, 2176, 347, 2429, 2177, 2445, 2178, 2447, 58, 2480, 390, 452, 554, 555, 313, 92, 275, 335, 428, 167, 302, 2173, 1538) GROUP BY playlists.id ORDER BY count(*) desc
为什么我的查询适用于开发而不适用于生产?
查询
@playlist_ids = @playlist.user_ids
@more_playlists = Playlist.joins(:users).where.not('playlists.id = ? OR playlists.id = ?', 30, 41).where(users: {id: @playlist_ids}).group('playlists.id').order('count(*) desc')
协会:
class Playlist < ActiveRecord::Base
has_many :playlist_users
has_many :users, :through => :playlist_users
end
class PlaylistUser < ActiveRecord::Base
belongs_to :playlist
belongs_to :user
end
class User < ActiveRecord::Base
has_many :playlist_users
has_many :playlists, :through => :playlist_users
end
更新
这很奇怪,我按照 trincot 的建议将 Playlist.name 添加到 GROUP BY 中:
@playlist_ids = @playlist.user_ids
Playlist.select('playlists.id, playlists.name')
.joins(:playlist_users)
.where('playlists.id NOT IN (30, 41)')
.where(playlist_users: {user_id: @playlist_ids})
.group('playlists.id, playlists.name')
.order('count(*) desc')
但是我得到了一个类似的错误,只是现在它告诉我必须在 GROUP BY 子句中包含 Playlist
属性 subject_id
:
PG::GroupingError: ERROR: column "playlists.subject_id" must appear in the GROUP BY clause or be used in an aggregate function
但我并没有在查询中的任何地方引用 subject_id
,甚至在页面的模型、控制器或视图中。那个专栏到底为什么要参与其中?
根据 PostgreSQL documentation 您的陈述无效:
When GROUP BY is present, it is not valid for the SELECT list expressions to refer to ungrouped columns except within aggregate functions, since there would be more than one possible value to return for an ungrouped column.
如果你说它在你的开发环境中工作,那一定意味着环境有另一个数据库引擎(版本)运行。
您应该使用这样的语句,其中 SELECT
子句中的字段列表与 GROUP BY
子句中给出的列表相同:
SELECT playlists.id, playlists.name, ...
FROM playlists
INNER JOIN playlist_users ON playlist_users.playlist_id = playlists.id
WHERE playlists.id NOT IN (30, 41)
AND playlist_users.user_id IN (your_long_list_comes_here)
GROUP BY playlists.id, playlists.name, ...
ORDER BY count(*) desc
请注意,您实际上不需要加入 users table 以获得您感兴趣的结果,因此我删除了它并替换了 [= 上的测试31=]user_id 相应地。此外,使用 IN
运算符可以更简洁地表达 playlists.id 上的条件。
对应的 Active Record 查询为:
Playlist.joins(:playlist_users)
.where('playlists.id NOT IN (30, 41)')
.where(playlist_users: {user_id: @playlist_ids})
.select('playlists.id, playlists.name')
.group('playlists.id, playlists.name')
.order('count(*) desc')
您必须在 select
和 group
参数中添加您需要的任何其他字段。