Ошибка запроса Codeigniter 3.0

Дублируйте эту таблицу: User_Posts

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

Мне нужно получить ранг элемента внутри этой категории. Поэтому ID: 19344 будет иметь позицию позиции 2, с 4 upvotes, за 12342 с 6 upvotes. Ранг определяется счетом (upvotes-downvotes) в пределах этой категории.

Итак, я написал этот запрос 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'

Возвращается ко мне (Rank = 2) при запуске непосредственно в mysql. Это правильный результат

Однако, когда я пытаюсь построить его через построитель запросов кода-воспламенителя, я получаю

$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();

возвращает мне пустой результат: array (rank = > );

тогда мой вопрос... но почему?

Я также согласен, что ответ будет альтернативным способом запуска этого запроса из построителя запросов с воспламенением кода, но в идеале я хотел бы знать, почему эта вещь нарушена.

Ответы

Ответ 1

У меня была аналогичная проблема в прошлом, оказалось, что мне сначала нужно инициализировать переменную с помощью отдельного запроса, я не уверен, что это все еще так, но все равно дайте ему попробовать.

//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();

Ответ 2

Я точно не знаю, почему ваш код не работает. Я написал другое решение, которое сработает. Попробуйте ввести код.

$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();

Ответ 3

Записать сохраненную функцию для выполнения запроса. Тогда Codeigniter просто

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

Ограничение: поскольку вы не можете выполнять PREPARE внутри хранимой функции, эта функция обязательно будет специфичной для одной таблицы User_Posts.

Ответ 4

Я не совсем уверен, что это проблема, но я бы инициализировал @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 undefined (NULL) и остается таким образом, пока вычисляется rank (NULL + 1 = NULL), после чего ему присваивается значение 0. Таким образом, rank возвращается как NULL, и вы получаете ['rank'=>].

Выполнение этого снова в постоянном соединении (непосредственно в MySQL) даст вам правильный результат, так как @rownum начнет с значения 0 из предыдущего запроса и rank будет рассчитан правильно.

Я предполагаю, что codeigniter запускает новое соединение/транзакцию каждый раз, когда выполняется запрос, а @rownum начинается с NULL каждый раз, предоставляя ['rank'=>].