简体   繁体   English

如何改善分页的SQL查询?

[英]How to improve SQL query for pagination?

I'm working with the database and servlets, there was such a problem. 我正在使用数据库和servlet,出现了这样的问题。 I need to receive data from the database of 6 pieces per page, for this I made such a request 我需要从数据库中接收每页6条的数据,为此,我提出了这样的要求

SELECT *, COUNT(*) AS 'count' 
FROM product
INNER JOIN product_category
  on product.product_category_id = product_category.id 
INNER JOIN  company_manufacturer_product 
  on product.company_manufacturer_product_id =
     company_manufacturer_product.id
GROUP BY 1 LIMIT 6 OFFSET 0;

where 6 is the maximum number of items per page and 0 is the page number multiplied by the maximum quantity of goods. 其中6是每页的最大项目数,0是页数乘以最大商品数量。 But with such an implementation on the second page I have duplicate products how can i improve it? 但是通过第二页上的这种实现,我有重复的产品我该如何改进它?

The part of the code where I form the request: 我形成请求的代码部分:

StringBuilder startResponse = new StringBuilder("SELECT *, COUNT(*) AS 'count' FROM product " +
                "INNER JOIN product_category on product.product_category_id = product_category.id " +
                "INNER JOIN company_manufacturer_product on product.company_manufacturer_product_id=company_manufacturer_product.id");
if (nonNull(form.getProductMax()) && nonNull(form.getPage())) {
            startResponse.append(" LIMIT ").append(form.getProductMax()).append(" OFFSET ").append(form.getPage() * form.getProductMax());
        }

My database respone without LIMIT and OFFSET: 我的数据库在没有LIMIT和OFFSET的情况下响应:

在此处输入图片说明

My database respone when I use the query that described above, this request is sent to the database when I turn to the first page with the goods: 当我使用上述查询时,我的数据库将响应,当我转到商品的第一页时,此请求将发送到数据库: 在此处输入图片说明

When I turn to the second page with goods, I send such a request to the database 当我转到商品的第二页时,我将这样的请求发送到数据库

SELECT * , COUNT(*) AS 'count' 
FROM product 
INNER JOIN product_category
  on product.product_category_id = product_category.id
INNER JOIN company_manufacturer_product 
  on product.company_manufacturer_product_id = 
     company_manufacturer_product.id
GROUP BY 1 LIMIT 6 OFFSET 6;

and i have response like that: 我有这样的回应:

在此处输入图片说明

I can not understand what the problem is. 我不明白是什么问题。 I have to use requests through COUNT! 我必须使用COUNT个请求! How prove it? 如何证明呢?

Not against the solution of this question, according to the above method, adding order by to original sql can solve the problem. 不反对这个问题的解决方案,根据上述方法,对原始sql添加order by即可解决问题。 But I think I have a better practice for pagination: using parameters like has_more , last_product_id and limit_num to connect clients with server. 但是我认为我有更好的分页习惯:使用has_morelast_product_idlimit_num类的参数将客户端与服务器连接。

has_more indicates more data in server whether or not left; has_more指示服务器中是否剩余数据; last_product_id indicates the id of last response data; last_product_id表示最后响应数据的id; limit_num indicates the number of per page. limit_num表示每页的数量。

So, client can using has_more to determine sending a request or not, if it is, client sends a request with last_product_id and limit_num to server; 因此,客户端可以使用has_more来确定是否发送请求,如果是,则客户端向服务器发送带有last_product_idlimit_num的请求; and for server, the sql can be this: 对于服务器,sql可以是这样的:

select * from table where id < $last_product_id order by id desc
limit $limit_num + 1; =>$datas

And, count($datas) and $limit_num to calculate the value of has_more and last_product_id : 并且,count($ datas)和$ limit_num可以计算has_morelast_product_id的值:

$has_more = 0;
$data_num = count($datas);
if ($data_num > $page_limit) {
    $has_more = 1;
    array_pop($datas);
    $data_num--;
}

$last_product_id = end($datas)['id'] ?? 0; 

SELECT *,COUNT(product.id)作为'count',来自产品INNER JOIN在product.product_category_id上的product_category = product_category.id INNER JOIN company_manufacturer_product在product.company_manufacturer_product_id = company_manufacturer_product.id上按product.id分组按product.id进行订购SET LIMIT 6 OFF 0;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM