2011-06-20 12 views
3

でSQL変数を使用して:レール私はこのクエリを持って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 
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: 

どうすればいいですか?

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

だからではなく、括弧を使用しての配列にそれを置くしようとする場合があります:それはこの構文であるAPIによって

おかげ

+0

私はこのようなことを見たことがありません。これは適切なMySQLクエリか別の方言ですか? – Wukerplank

答えて

7

find_by_sqlは、単一のstatementで動作するためです。

設定変数は別々の文で発生します。 setは、具体的にはDatabase Administrationセクションにあり、番号12.4.4、およびselectは、Data Manipulationセクション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つを望む可能性が高い、またはあなたがいないことを知っていれば、 。

お楽しみください!

-2

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"] 
+0

Sam @current_groupと@current_countはルビ変数ではなく、MYSQL変数です。私がphpmyadminでこれを起動すると動作します。しかし、レールでfind_by_sqlメソッドno。それで問題は、どうすればいいのですか?ああ、私は参照してください –

+0

。それだけで艶をかけた。 – s84

関連する問題