2016-01-24 12 views
14

Duplica questa tabella: User_PostsCodeigniter 3.0 interrogazione bug

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

ho bisogno di ottenere il rango di un elemento al suo interno di categoria. Pertanto, ID: 19344 avrà Rank position 2, con 4 upvotes, dietro 12342 con 6 upvotes. Il grado è determinato dal conteggio (upvotes-downvotes) nella sua categoria.

Così ho scritto questa query 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' 

ritorni a me (Rango = 2), quando eseguito direttamente in mysql. Questo è il risultato corretto

Tuttavia quando provo a costruirlo attraverso generatore di query di codice-accenditore mi vengono i

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

ritorna a me un risultato vuoto: array (rango =>);

quindi la mia domanda è ... ma perché?

Accetterò anche una risposta sarà un modo alternativo per eseguire questa query dal generatore di query code-igniters, ma idealmente mi piacerebbe sapere perché questa cosa è rotta.

+0

Non è possibile semplificare l'SQL per 'SELECT (Upvotes - Downvotes) AS rank FROM User_Posts WHERE CAT = 'Blogs' AND POST_ID = 19344;'? Sembra che sarebbe troppo semplice da implementare anche nel generatore di query di CI. – quickshiftin

+0

Il rango @quickshiftin non è il numero di (upvotes-downvotes) ma è la posizione dell'articolo rispetto a ciascun altro elemento nella stessa categoria. – Edward

+0

Ok, come si tiene conto dei legami in (upvotes-downvotes) per una data categoria? – quickshiftin

risposta

4

Ho avuto un problema simile in passato, risulta ho dovuto inizializzare la variabile con una query separata prima, io non sono sicuro se questo è ancora il caso, ma fare un tentativo comunque.

//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

Questa era la soluzione per iniziare la variabile. Molto apprezzato. – Edward

+2

@Edward ... ma lo sapevi già! Hai appena fatto nel posto sbagliato nella tua query. N.B. Se lo fai in questo modo, puoi rimuovere ', (SELECT @rownum: = 0) t2' dalla tua query. – Arth

2

Scrivere una funzione memorizzata per eseguire la query. Poi hanno Codeigniter fare semplicemente

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

Limitazione: Dal momento che non si può fare PREPARE all'interno di una funzione memorizzata, questa funzione sarà necessariamente essere specifico di un tavolo, User_Posts.

5

Esattamente non so perché il tuo codice non funziona. Ho scritto un'altra soluzione che funzionerà. Prova sotto il codice.

$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

Non sono del tutto sicuro se questo è il problema, ma sarei inizializzazione @rownum nella subquery:

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 = ? 

altrimenti sarei preoccupato che @rownum è indefinito (NULL) e rimane in questo modo mentre viene calcolato rank (NULL + 1 = NULL), solo in seguito viene assegnato il valore di 0. Pertanto, rank viene restituito come NULL e si ottiene ['rank'=>].

L'esecuzione di questo nuovo in un collegamento costante (direttamente in MySQL) sarebbe allora gli danno il risultato corretto come @rownum sarebbe iniziare dal valore 0 dalla query precedente ed rank sarebbe calcolato in modo corretto.

Sto indovinando codeigniter avvia una nuova connessione/transazione ogni volta che viene eseguita la query e @rownum inizia a NULL ogni volta, dando ['rank'=>].