mysql - 如何在不切割特定列的情况下对sql表进行分页

标签 mysql sql

想象一下按国家名称排序的示例表数据:

CustomerID  Country
12          Argentina
54          Argentina
20          Austria
59          Austria
50          Belgium
76          Belgium
77          Belgium
15          Brazil
21          Brazil
31          Brazil
34          Brazil
88          Brazil
10          Canada
42          Canada
51          Canada
73          Denmark
74          France
84          France
85          France
1           Germany
6           Germany
17          Germany
37          Ireland
27          Italy
49          Italy
66          Italy
2           Mexico
3           Mexico

我怎么能将它分页限制在不超过 10 个(有异常(exception)),而不返回切入国家/地区组中间的页面。这是预期的结果

page = 1 返回的变量

12          Argentina
54          Argentina
20          Austria
59          Austria
50          Belgium
76          Belgium
77          Belgium

page = 2 返回的变量

15          Brazil
21          Brazil
31          Brazil
34          Brazil
88          Brazil
10          Canada
42          Canada
51          Canada
73          Denmark

page = 3 返回的变量

74          France
84          France
85          France
1           Germany
6           Germany
17          Germany
37          Ireland

page = 4 返回的变量

27          Italy
49          Italy
66          Italy
2           Mexico
3           Mexico

10 个限制的异常(exception)情况是同一国家/地区超过 10 行。

我尝试了一些限制和偏移量的东西,但仍然没有找到任何干净/简单的查询。我这样做是为了分块。任何帮助深表感谢。您可以使用数据 HERE!

最佳答案

您可以使用变量在 MySQL 中执行此操作。这非常具有挑战性,因为您需要跟踪页面和页面中的行号。但是,MySQL 只真正支持每个变量一个表达式。更具体地说,它不保证 SELECT 中表达式的求值顺序。

逻辑是为页面添加一个新列,您可以将其用于分页。逻辑是这样的:

select t.*,
       @p := (case when @c = country
                   then (case when @rn = 10  -- a county has more than 10 rows
                              then (case when (@rn := 1) = null then null -- never happens
                                         else (@p := @p + 1) 
                                    end)
                              else (case when (@rn := @rn + 1) = null then null -- never happens
                                         else @p
                                    end)
                         end)
                    when (@rn + cnt > 10)  -- start a new page
                    then (case when (@rn := 1) = null then null -- never happens
                               else (@p := @p + 1)
                          end)
                    else (case when (@rn := @rn + 1) = null then null -- never happens
                               else @p
                          end)
             end) as page
from (select t.*, c.cnt
      from t join
           (select country, count(*) as cnt
            from t
            group by country
           ) c
           on t.country = c.country
      order by t.country, t.CustomerID
    ) t cross join
    (select @rn := 0, @p := 0, @c := '') params
order by page, t.country, t.CustomerId;

Here是一个 db<>fiddle,显示代码工作(至少在某些情况下)。

关于mysql - 如何在不切割特定列的情况下对sql表进行分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53127995/

相关文章:

php - 使用 Laravel 4 更新/插入连接 View

.net - 如何在源代码管理中处理 SQL Server CE?

sql - 为什么这个索引会使 SELECT GROUP BY 查询变慢?

sql - 如何在 Snowflake 中将字符串拆分为字符?

php - 我需要 PDO 连接成功的确认

php - 控制单击“赞”按钮后在 Facebook 个人资料中显示的屏幕截图和标题

mysql - JOIN 中的多个 COUNT()

mysql - 如何删除 'duplicate'记录?

php - MYSQL对当前行计数子查询

sql - 一行中多个表的值