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

これらはすべて単一のトランザクションで実行され、トランザクション ブロック内の変数/設定はクエリ間で保持されます。ただし、クエリごとに 1 つのステートメントにバインドされます。セット全体をラップする実際のトランザクションなしでそれを行う方法があるかもしれませんが、私はそれを探していません-おそらくあなたはそれを望んでいるか、そうでないことがわかっている場合は非常に具体的なものを探す必要があります.

楽しみ!

于 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 に答える