如何使用ActiveRecord在MySQL上使用DISTINCT ON

时间:2018-12-20 12:37:04

标签: mysql ruby-on-rails activerecord

想要所有不同用户的所有最新访问。

为此,我正在使用以下查询

Event.order(time: :desc).select('DISTINCT ON(user_id) user_id, time')

获取SQL语法错误。

ActiveRecord::StatementInvalid (Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'ON(user_id) user_id, time FROM `events` ORDER BY `events`.`time` DESC ' at line 1: SELECT  DISTINCT ON(user_id) user_id, time FROM `events` ORDER BY `events`.`time` DESC LIMIT 11)

事件表列名称

["id", "visit_id", "user_id", "name", "properties", "time"] 

有人可以帮我吗

期望这样的输出

{ 21 => "2018-12-18 09:44:59", 42 => "2018-12-19 12:08:59"}

21是user_id,值是上次访问时间

使用mysql作为数据库

2 个答案:

答案 0 :(得分:1)

就像我在评论DISTINCT ON(column), *中所说的那样,它是PostgreSQL SQL语法。

下面的查询需要在MySQL中重写

SELECT 
 DISTINCT ON(user_id) AS user_id, time
FROM 
 <table>
ORDER BY 
 time DESC
LIMIT 11 

最容易做到的是使用SUBSTRING_INDEX(GROUP_CONCAT(..))
我相信以下查询应能为您提供正确的结果。

SET SESSION group_concat_max_len = @@max_allowed_packet;

SELECT 
   user_id
 , SUBSTRING_INDEX(
     GROUP_CONCAT(time
                  ORDER BY
                     time DESC
     )
     , ','
     , 1
 ) AS time
FROM 
 <table>
GROUP BY 
 user_id
ORDER BY 
 time DESC
LIMIT 11

答案 1 :(得分:1)

因此,您希望所有用户访问都具有上次访问时间。

您可以将DISTINCTGROUP函数一起使用,而不是使用MAX函数。

查询看起来像

Events.group(:user_id).maximum(:time)

这将输出您想要的结果

{21=>Tue, 18 Dec 2018 11:15:24 UTC +00:00, 23=>Thu, 20 Dec 2018 06:42:10 UTC +00:00}

希望这对您有用。

仅供参考 DISTINCT ON(列)。是PostgreSQL语法。