带有联接的SQL复杂查询
我遇到了一个查询问题。 让我解释一下我想要的东西: 对于bravity的缘故,让我们说,我有三个表:带有联接的SQL复杂查询
-Offers
-Ratings
-Users
现在我想做的事是要创建SQL查询:
我希望列出其所有字段和附加临时列这并不是存储在任何称为AverageUserScore的地方。
此AverageUserScore是抓取属于特定用户的所有优惠的产品,然后抓取属于这些优惠的所有评分,然后评估这些评分的平均值 - 此平均分为AverageUserScore。
要进一步解释它,我需要这个查询Ruby on Rails应用程序。在浏览器内部应用程序中,您可以看到其他用户的所有优惠,其中AverageUserScore作为最后一列。
协会:
- 发售有许多收视率
- 发售属于用户
- 评级属于提供
- 用户有很多的优惠
Assumpti附加组件:
- 你确实有一个数字列在您的评级模型(任何类型的SQL的
AVG
是罚款)。在我的示例中,我使用了一列ratings.rating
。因为average_user_score
比较好。 - 你不介意没有得到没有任何优惠的用户:无论如何,他们的平均评分没有明确定义。
- 你不会偏离Rails的惯例足够有一个主键而不是
id
。
显示每个用户的优惠是一项直截了当的任务:在@users.each do |user|
的循环中,您可以做user.offers.each do |offer|
并进行设置。这里唯一的问题是它会为每个用户执行一个单独的查询。不好。
“提取报价”部分是一个标准的N + 1计数器,甚至可以看到in the guides。
@users = User.includes(:offers).all
这里有趣的部分只是获取平均值。
为此我打算使用Arel。它已经是Rails的一部分,ActiveRecord建立在它之上,所以你不需要额外安装任何东西。
你应该能够做一个加入这样的:
User.joins(offers: :ratings)
这样就不会(从过滤那些没有为用户提供了除)给你什么有趣的事。在内部,你会得到一个巨大的每一个评级加入相应的报价和该报价的用户。由于我们采用的是平均每位用户,因此我们需要group byusers.id
,有效地为每个users.id
值创建一个条目。也就是说,每个用户一个。用户列表,是的!
让我们停下来等一下,做一些分配让Arel相关的代码更漂亮。其实我们只需要两个:
users = User.arel_table
ratings = Rating.arel_table
好的。所以。我们需要获取用户列表(所有字段),并为每个用户获取他的优惠评分'rating
“字段中显示的平均值。因此,让我们来撰写这些SQL表达式:
# users.*
user_fields = users[Arel.star] # Arel.star is a portable SQL "wildcard"
# AVG(ratings.rating) AS average_user_score
average_user_score = ratings[:rating].average.as('average_user_score')
所有设置。准备好最终查询:
User.includes(:offers) # N+1 counteraction
.joins(offers: :ratings) # dat join
.select(user_fields, average_user_score) # fields we need
.group(users[:id]) # grouping to only get one row per user
请添加相关栏目。 –
我真的不知道该怎么做,这就是为什么我没有发表我的例子,我正在寻找一个人,至少让我指向正确的方向。 – MatthewK
如果没有至少需要@juergend要求的信息,我们无法帮助您。哪一列是评分表上的分数?你的外键是什么? –