Rails 3查询:将“选择”与“订单”一起使用时出错

Rails 3查询:将“选择”与“订单”一起使用时出错

问题描述:

我试图回答这个问题我在哪里遇到了这个问题。

I was trying to answer this question where I got this issue.

我有一个具有 id 的用户模型电子邮件名字列。因此,在单个查询中,我想选择具有不同 first_name 的用户,并按 email 对其进行排序,然后选择其 ID

I have a user model having id, email and first_name columns. So in single query I want to select users with distinct first_name, sort them by email and pluck their ID.

我该怎么做?

什么不起作用:


  1. User.select(:first_name).uniq.pluck(:id)

因为它会触发此SQL SELECT DISTINCT users。 id FROM users 。这是为用户选择不同的ID。但是我们要选择不同的first_name

because it fires this SQL SELECT DISTINCT "users"."id" FROM "users". This is selecting distinct id from user. But we want to select distinct first_name

User.order( email DESC)。pluck(:id).uniq

已生成SQL:选择用户。 id来自用户,按电子邮件DESC顺序。这将不起作用,因为生成的sql不会检查first_name的唯一性。

SQL generated: SELECT "users"."id" FROM "users" ORDER BY email DESC. This will not work because the sql generated is not checking for uniqueness of first_name.


您可以使用此 SQLFIDDLE 来测试SQL。

You could test the SQL with this SQLFIDDLE.

仅Sqlite和MySql支持此用法,而其他人则不支持。

Only Sqlite and MySql support this usage, but others don't.

请参阅此 PostgreSQL文档


在SQL-92标准中,ORDER BY子句只能使用结果列名称或数字

In the SQL-92 standard, an ORDER BY clause can only use result column names or numbers

在ORDER BY子句中也可以使用任意表达式,包括未出现在SELECT结果列表中的列。因此,以下语句是有效的:

It is also possible to use arbitrary expressions in the ORDER BY clause, including columns that do not appear in the SELECT result list. Thus the following statement is valid:


从分发者中选择名称ORDER BY代码;

SELECT name FROM distributors ORDER BY code;

此功能的局限性在于,应用于UNION,INTERSECT或EXCEPT子句结果的ORDER BY子句只能指定输出列名或数字,而不能指定表达式。

A limitation of this feature is that an ORDER BY clause applying to the result of a UNION, INTERSECT, or EXCEPT clause can only specify an output column name or number, not an expression.

对于您的情况,不需要使用uniq,因为所有用户ID都是不同的,所以为什么不尝试以下操作:

For your case, there is no need of using uniq, all user id distinct already, so why don't you try this:

User.order("email DESC").pluck(:id)

假设ID重复,则可以通过ruby而不是DB来唯一化。

Assuming the ids duplicated, you could uniq by ruby instead of DB.

User.order("email DESC").pluck(:id).uniq

该脚本将永远不会生成带有不同的sql。拔出后的 uniq Array#uniq 方法。

This script will never generate sql with distinct. This uniq after pluck is an Array#uniq method.