3

我有这个查询:

SET @current_group = NULL; 
SET @current_count = 0; 
SELECT user_id, MIN( created_at ) as created_at, CASE WHEN @current_group = user_id THEN @current_count WHEN @current_group := user_id THEN @current_count := @current_count + 1 END AS c 
FROM notifies 
G    ROUP BY user_id, c 
ORDER BY id desc LIMIT 0 , 10

如果我启动它就可以了

但如果我把它放在一个 find_by_sql 方法中,比如:

Notify.find_by_sql("SET @current_group = NULL; SET @current_count = 0; SELECT user_id, MIN( created_at ) as created_at, CASE WHEN @current_group = user_id THEN @current_count WHEN @current_group := user_id THEN @current_count := @current_count + 1 END AS c FROM notifies GROUP BY user_id, c ORDER BY id desc LIMIT 0 , 10")

它返回此错误:

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 'SET @current_count = 0; SELECT user_id, MIN( created_at ) as created_at, CASE WH' at line 1:

我能怎么做?

谢谢

4

2 回答 2

9

这是因为find_by_sql仅适用于单个语句

设置变量发生在单独的语句中。 set特别是在数据库管理部分,编号 12.4.4,select数据操作部分,编号 12.2.7。控制台(通常)允许多个语句,并保留变量,但 ActiveRecord 查询不允许。

为了允许多个语句,我认为您必须与数据库保持持久连接,而 Rails 不会这样做(编辑:通常)。但我不确定——如果其他人知道,我希望有一个更明确的理由。

编辑:实际上,我有一个解决方案给你。试试这个:

items = YourModel.transaction do
  YourModel.connection.execute("SET @current_group = NULL;")
  YourModel.connection.execute("SET @current_count = 0;")
  # this is returned, because it's the last line in the block
  YourModel.find_by_sql(%Q|
    SELECT user_id, MIN( created_at ) as created_at, CASE WHEN @current_group = user_id THEN @current_count WHEN @current_group := user_id THEN @current_count := @current_count + 1 END AS c 
    FROM notifies 
    GROUP BY user_id, c 
    ORDER BY id desc LIMIT 0 , 10
  |)
end

所有这些都在单个事务中运行,事务块内的任何变量/设置都将在查询之间保持不变。但是,您仍然必须为每个查询绑定一个语句。可能有一种方法可以在不包含整个集合的实际事务的情况下做到这一点,但我没有寻找它 - 很可能你想要一个,或者如果你知道你不知道你现在有一个非常具体的东西要寻找.

享受!

于 2012-03-01T21:57:18.900 回答
-2

根据 API,它是这样的语法:

Post.find_by_sql ["SELECT title FROM posts WHERE author = ? AND created > ?", author_id,  start_date]

因此,您可能想尝试将其放入数组而不是使用括号。

Notify.find_by_sql ["SET @current_group = NULL; SET @current_count = 0; SELECT user_id, MIN( created_at ) as created_at, CASE WHEN @current_group = user_id THEN @current_count WHEN @current_group := user_id THEN @current_count := @current_count + 1 END AS c FROM notifies GROUP BY user_id, c ORDER BY id desc LIMIT 0 , 10"]
于 2011-06-20T13:53:05.023 回答