2016-01-24 7 views
14

この表を複製:User_PostsCodeIgniterの3.0クエリバグ

ID  | Upvotes | Downvotes | CAT | 
___________________________________ 
42134 | 5  |  3 | Blogs| 
------------------------------------ 
12342 | 7  |  1 | Blogs| 
------------------------------------- 
19344 | 6  |  2 | Blogs| 
------------------------------------ 

を、私はそれのカテゴリ内のアイテムのランクを取得する必要があります。したがって、ID:19344はランクポジション2を持ち、アップフォートは4つで、12342の後ろに6つのアップフォートがあります。ランクは、そのカテゴリー内の(upvotes-downvotes)カウントによって決定されます。

私はこのMySQLクエリを書いています。 MySQLで直接実行私に

SELECT rank FROM (SELECT *, @rownum:[email protected] + 1 AS rank 
FROM User_Posts where CAT= 'Blogs' order by 
(Upvotes-Downvotes) DESC) d, 
(SELECT @rownum:=0) t2 WHERE POST_ID = '19344' 

戻り値(ランク= 2)。私は、コードイグナイタのクエリビルダーを通してそれを構築しようとすると、は、これは私が私には空の結果

$table = 'User_Posts'; 
$CAT= 'Blogs'; 
$POST_ID = '19344'; 

$sql = "SELECT rank FROM (SELECT *, @rownum:[email protected] + 1 AS 
rank FROM $table where CAT= ? 
order by (Upvotes-Downvotes) DESC) d, 
(SELECT @rownum:=0) t2 WHERE POST_ID= ?"; 

$query= $this->db->query($sql, array($CAT,$POST_ID))->row_array(); 

リターンを得る

しかし、正しい結果である:配列(ランク=>);

ですから、私の質問は... ですが、なぜですか?

また、コード・イグニッタ・クエリー・ビルダーからこのクエリーを実行する代わりに、この問題がなぜ壊れているのかを知りたいと思っています。

+0

SQLを 'SELECT(Upvotes - Downvotes)AS rank FROM User_Posts WHERE CAT = 'Blogs'とPOST_ID = 19344;に単純化できませんか? CIのクエリービルダーに実装するのは簡単すぎるようです。 – quickshiftin

+0

@quickshiftin rankは(upvotes-downvotes)の数ではありませんが、同じカテゴリ内の他のアイテムに関するアイテムの位置です。 – Edward

+0

あなたは特定のカテゴリの(upvotes-downvotes)の関係をどうやって説明していますか? – quickshiftin

答えて

4

私は過去に同様の問題を持っていた、私はこれはまだケースであるかどうかわからないけど、とにかく試してくださいそれを与える、私が最初に別のクエリで変数を初期化しなければならなかったが判明しました。

//initialize the variable, before running the ranking query. 
$this->db->query('SELECT 0 INTO @rownum'); 
$query= $this->db->query($sql, array($CAT,$POST_ID))->row_array(); 
+0

これは変数を初期化するための解決策でした。とても有難い。 – Edward

+2

@エドワード...しかし、あなたはすでにこれを知っていた!あなたはあなたの質問の間違った場所でそれをやっただけです。 N.B.このようにすれば、クエリから '(SELECT @rownum:= 0)t2'を取り除くことができます。 – Arth

2

クエリを実行するためのストアドファンクションを作成します。そして、CodeIgniterのを持っているだけで

query("SELECT PostRank(?,?)", $CAT, $POST_ID); 

制限を行います。あなたはストアド・ファンクション内PREPAREを行うことができないので、この機能は必ずしも一つのテーブル、User_Postsに固有のものになります。

5

あなたのコードが動作していない理由を正確にはわかりません。私はそれが動作する別の解決策を書いた。以下のコードを試してください。

$select="FIND_IN_SET((upvote-downvote), (SELECT GROUP_CONCAT((upvote-downvote) ORDER BY (upvote-downvote) DESC) as total FROM (User_Posts))) as rank"; 
$this->db->select($select,FALSE); 
$this->db->from('(User_Posts)',FALSE); 
$this->db->where('ID',19344); 
$this->db->where('CAT','Blogs'); 
$query = $this->db->get(); 
1

私はこれが問題であれば、完全にわからないんだけど、私はサブクエリで@rownumを初期化するだろう:

SELECT rank 
    FROM (
    SELECT *, 
      @rownum:[email protected] + 1 AS rank 
     FROM $table 
     JOIN (SELECT @rownum := 0) init 
     WHERE CAT= ? 
    ORDER BY (Upvotes-Downvotes) DESC 
     ) d 
WHERE post_id = ? 

そうでなければ、私は@rownumが定義されていないことを心配するだろう(NULLrankが計算されている間に(NULL + 1 = NULL)、そのあとに0という値が割り当てられます。したがってrankNULLとして返され、['rank'=>]となります。 @rownumは、前のクエリから値0から開始するとrankが正しく計算されるよう

(直接MySQLで)常時接続で再びこれを実行すると、その後、あなたに正しい結果を与えるだろう。

私は、クエリが実行されるたびにcodeigniterが新しい接続/トランザクションを開始し、@rownumが毎回NULLで始まり、['rank'=>]となると推測しています。