-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
QueryBuilder + GROUP BY + Pagination = wrong number of results #2065
Comments
Can you print the |
$paginator
After ->getPaginate();
|
Indeed, I do have the same problem :( |
Also have the same problem and I also noticed that is happening because of joins too, not only for group by |
Can you give a list structure, I simulate some data under test. |
CREATE DATABASE IF NOT EXISTS `craigslist` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `craigslist`;
-- MySQL dump 10.13 Distrib 5.5.35, for debian-linux-gnu (x86_64)
--
-- Host: localhost Database: craigslist
-- ------------------------------------------------------
-- Server version 5.5.35-0+wheezy1
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
/*!40101 SET NAMES utf8 */;
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
/*!40103 SET TIME_ZONE='+00:00' */;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
--
-- Table structure for table `categories`
--
DROP TABLE IF EXISTS `categories`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `categories` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `data`
--
DROP TABLE IF EXISTS `data`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `data` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`title` varchar(255) DEFAULT NULL,
`href` varchar(255) DEFAULT NULL,
`image` varchar(255) DEFAULT NULL,
`longitude` varchar(255) DEFAULT NULL,
`latitude` varchar(255) DEFAULT NULL,
`price` decimal(11,2) DEFAULT NULL,
`area` varchar(255) DEFAULT NULL,
`url_id` int(11) DEFAULT NULL,
`created_at` date DEFAULT NULL,
`good` smallint(2) DEFAULT NULL,
`called` smallint(2) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `URL_ID` (`url_id`)
) ENGINE=InnoDB AUTO_INCREMENT=4390612285 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `sub_domains`
--
DROP TABLE IF EXISTS `sub_domains`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `sub_domains` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=417 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
--
-- Table structure for table `url`
--
DROP TABLE IF EXISTS `url`;
/*!40101 SET @saved_cs_client = @@character_set_client */;
/*!40101 SET character_set_client = utf8 */;
CREATE TABLE `url` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`sub_domain_id` int(11) NOT NULL,
`items_count` int(11) DEFAULT '0',
`last_item` int(20) DEFAULT NULL,
`params` text,
`category_id` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `SUB_DOMAIN` (`sub_domain_id`),
KEY `CATEGORY_ID` (`category_id`),
CONSTRAINT `FK_URL_CATEGORY_ID` FOREIGN KEY (`category_id`) REFERENCES `categories` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_URL_SUB_DOMAIN_ID` FOREIGN KEY (`sub_domain_id`) REFERENCES `sub_domains` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=831 DEFAULT CHARSET=utf8;
/*!40101 SET character_set_client = @saved_cs_client */;
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
-- Dump completed on 2014-03-25 9:22:39 $currentPage = $this->request->getQuery('page', 'int');
$builder = $this->modelsManager->createBuilder();
$builder
->columns(array(
'Url.*',
'COUNT(gData.id) as data_count_total',
'SUM(if(gData.good = 1, 1, 0)) AS data_count_good',
'ROUND((SUM(if(gData.good = 1, 1, 0)) / COUNT(gData.id)) * 100, 2) AS data_good_percentage',
'Categories.name as category_name',
'Categories.id as category_id'
))
->from('Categories')
->groupBy('Categories.id, Url.params')
->join('Url', 'Url.category_id = Categories.id')
->leftJoin('Data', 'Url.id = gData.url_id', 'gData')
;
$paginator = new Phalcon\Paginator\Adapter\QueryBuilder(
array(
"builder" => $builder,
"limit" => 100,
"page" => $currentPage
)
);
$page = $paginator->getPaginate(); |
i saw the breaking pagination on joins on magento where the solution was to reset the select as follow: public function getSelectCountSql()
{
$this->_renderFilters();
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
$countSelect->reset(Zend_Db_Select::COLUMNS);
// Count doesn't work with group by columns keep the group by
if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
$countSelect->reset(Zend_Db_Select::GROUP);
$countSelect->distinct(true);
$group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
$countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
} else {
$countSelect->columns('COUNT(*)');
}
return $countSelect;
} |
a quick and dirty solution i think would be: $dataCount = $builder->getQuery()->execute()->count();
$page->next = $page->current + 1;
$page->before = $page->current - 1 > 0 ? $page->current - 1 : 1;
$page->total_items = $dataCount;
$page->total_pages = ceil($dataCount / 100);
$page->last = $page->total_pages; |
Having the same issue... @phalcon when there will be a fix for this? |
I am afraid is not an easy fix. I have reasons to believe is zend common issue. You may avoid by creating another query collection clone count. I am also intersting in an out of the box solution but i also think is not very easy. Regards, |
I believe I've previously experienced a similar issue with Zend. The workaround was similar to the workaround I got to with Phalcon. But, I would like to hear an official word from @phalcon team about this issue. |
I've wrapped the @avra911 solution in a child class of Also I'm not sure if it will work in a database other than MySQL since the syntax may differ, but I've checked that PHQL parses |
This solution does not fix entire bug. |
Actually the behaviour is:
You can see the code here, if you find a solution please submit a pull request to 2.0.0 |
This function: public static function buscarNoticia($searchParams) {
$builder = \Phalcon\DI::getDefault()->getModelsManager()->createBuilder()->from('Application\Models\Noticia');
$builder->leftJoin('Application\Models\NoticiaVersao', 'Application\Models\Noticia.id = Application\Models\NoticiaVersao.noticia_id');
if (is_array($searchParams)) {
//verifica editoria
if ($searchParams['editoria_id']) {
$editoria_id = $searchParams['editoria_id'];
$builder->andWhere('Application\Models\Noticia.editoria_id = '.$searchParams['editoria_id']);
}
if ($searchParams['search']) {
$builder->leftJoin('Application\Models\AssuntosNoticia', 'Application\Models\Noticia.id = Application\Models\AssuntosNoticia.noticia_id');
$builder->leftJoin('Application\Models\AssuntosEditoria', 'Application\Models\AssuntosEditoria.id = Application\Models\AssuntosNoticia.assunto_id');
$builder->leftJoin('Application\Models\FonteNoticia', 'Application\Models\Noticia.id = Application\Models\FonteNoticia.noticia_id');
$builder->leftJoin('Application\Models\Fonte', 'Application\Models\Fonte.id = Application\Models\FonteNoticia.fonte_id');
$builder->andWhere('Application\Models\Noticia.titulo like :search: or Application\Models\AssuntosEditoria.titulo = :assunto: or Application\Models\Fonte.nome like :search:',array('search' => "%".$searchParams['search']."%",'assunto' => $searchParams['search']));
$builder->groupBy('Application\Models\Noticia.id');
}
}
$builder->orderBy('Application\Models\NoticiaVersao.data_inicio DESC');
return $builder;
} Are used in this code: use Phalcon\Paginator\Adapter\QueryBuilder as Paginator;
$paginator = new Paginator(array(
'builder' => Noticia::buscarNoticia($searchParams),
'limit' => $pageLimit,
'page' => $currentPage
)); The limit still doesn't work on my paginator. Is this wrong? |
I do have the same problem :((( |
@erickskrauch what's version with you? |
1.3.2 TS x86 |
how the source code to set autoincrement in the framework Phalcon .. ?? |
Hello, I have checked in all phalcon 2.0.x tags and in the master and commits of usernaem are not present. So, using GROUP BY with QueryBuilder paginator adapter doesn't work at all. |
I have the same problem. I use query builder with group by and paginator. Total items count is equal to 1. When will it be fixed? |
@hailie-rei Create please separated issue by providing Phalcon version and small script to reproduce |
@sergeyklay Okay, I'll do that :) |
i have the same problem. how to fix it? https://forum.phalconphp.com/discussion/18799/dateformat-group-bug-with-createbuilder-and-paginator |
Criei um novo extendendo a classe original:
|
I'm having an issue when doing pagination with a group by and query builder. If I do the following:
It says 1073 results. In reality there are 17K+ results, causing the wrong number of pages. This is using 1.2.6.
If I do:
It has the correct number of rows.
The text was updated successfully, but these errors were encountered: