8
votes

Comptez les lignes avant d'ajouter un autre code de déclaration limite?

J'ai couru dans un problème ...

J'ai un tas d'où des stations comme ... xxx

puis une instruction limite xxx

et enfin ma déclaration GET xxx

Mon problème est que j'ai besoin de compter les résultats avant ma déclaration limite, à obtenir les rangées totales sans la limite .. donc j'ai essayé ceci .. xxx

ceci compte mes lignes avec les instructions suivantes. Toutefois, la déclaration GET obtient des disques sans la précédente où les déclarations fonctionnent.

Ce n'est pas visible, mais il existe une grande quantité de code de code qui manipule plus d'instructions et saisir des objets dans les URL, donc je préférerais ne pas exécuter la récupération de Données deux fois pour résoudre ce problème ...

acclamations!


1 commentaires

Vous devrez faire deux questions, à moins que vous ne souhaitiez tirer toutes les lignes à chaque fois. La deuxième requête pourrait simplement être un Sélectionnez le compte (ID) comme Row_Count à partir de la table où les conditions


7 Réponses :


5
votes
function get_data($limit = 10, $offset= 0)
{
    $table = 'table-name';
    $where = array('Pool' => 1, 'Beedrooms >=' 3);

    $return['data']  = $this->db->from($table)->where($where)->limit($limit, $offset)->get();
    $return['count'] = $this->db->from($table)->where($where)->count_all_results();

    return $return;
}

1 commentaires

Je viens d'essayer cela et j'ai quitté la limite sur la ligne "Count_All_Results ()" par erreur et je suis toujours compté tous les articles qui correspondent à mon "où" ... Je ne sais pas si un bogue ou une fonctionnalité modifier: seulement travaillé pendant mon décalage == 0 Je pense que c'est un bug



1
votes

Il est évident que vous auriez besoin d'utiliser deux requêtes différentes. Il serait optimal de le faire le plus rapidement possible à l'aide d'une seule requête, mais puisque vous devez obtenir tous les enregistrements avant la deuxième requête, nous devons utiliser deux requêtes.

Cependant, vous pouvez optimiser la première requête en fonction du moteur que vous utilisez avec MySQL. Si vous utilisez InnoDB, vous devez utiliser SELECT Count (*) à partir de Cause La taille totale de la ligne est mise en cache dans InnoDB.

Je pense que comte_all_rows utilise comptez (*) pour la performance et vous devez être trié à l'aide de cette direction.

avec myisam, vous pouvez utiliser compter () .

Donc, vous avez une fonction de comptage dans votre classe modèle qui renvoie le nombre de pour votre table, puis vous pouvez appeler la fonction pour insérer / mettre à jour / obtenir des données de votre base de données.


0 commentaires

18
votes

Je sais que c'est une ancienne question, mais je viens de courir dans ce problème et j'ai eu une solution différente.

L'idée est de prendre une copie de la classe DB avant la limite et le décalage. xxx


1 commentaires

Pourquoi la copie peu profonde?



5
votes
    $this->db->select('*');
    $this->db->from('users');
    $this->db->where('active',$status);

    //open1 here we copy $this->db in to tempdb and apply 
    //count_all_results() function on to this tempdb
    $tempdb = clone $this->db;
    $num_results= $tempdb->count_all_results();   

    // now applying limit and will get actual result 
    $this->db->limit(10);

    $this->db->get();
    $query = $this->db->last_query();
    $res = $this->db->query($query);        

    $data_array = array('num_results' => $num_results, 'results' => $res->result() );
    return $data_array;

2 commentaires

Merci mec! Vous avez sauvé mon temps.


Il n'est pas nécessaire de cloner l'objet DB. Utilisez simplement "$ NUML_ROWS = $ ceci-> dB-> comte_all_results ('', false);" avant de limiter le résultat.



1
votes

Vous pouvez utiliser sql_calc_found_rows de mysql xxx

Sélectionnez Found_Rows ();

Ceci utilise MySQL, vous devrez peut-être vérifier comment Pour utiliser IT CodeIntor Way.

Référence:

https://dev.mysql.com/doc/refman/5.7/fr/information-fonctions.html#function_found-aux


1 commentaires

Trouvé celui-là aussi et il semble être le moyen le plus élégant. Certains détails sont situés ici: Percona .com / blog / 2007/08/28 / ...



14
votes

Je sais que c'est une vieille question mais j'ai trouvé une solution assez simple. XXX

J'espère que cela aide quelqu'un


2 commentaires

Super trouver. : +1: fonctionne comme un charme


Solution assez soignée



0
votes

Je sais que cette question est vieille mais j'ai eu le même problème et j'ai une solution plus simple que celle affichée ici. Pas besoin de construire la requête deux fois et n'est pas nécessaire de cloner la classe dB code>. Comptez simplement le résultat sans reposer le constructeur de requêtes après avoir ajouté le où code> pièce, puis vous ajoutez la limite code> code> et exécutez votre requête.

$this->db->where('Pool', 1);
$this->db->where('Beedrooms >=' 3);
$count = $this->db->count_all_results('table-name', false); // No reset query builder
$this->db->limit($limit, $offset)
$result = $this->db->get();


0 commentaires