如何在不削减特定列的情况下分页sql表

时间:2018-11-03 02:57:59

标签: 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个的限制(有例外),而不能返回切入国家/地区组中间的页面。这是预期的结果

页面数= 1的变量

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

页面数= 2的变量

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

页面= 3个返回值的变量

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

页面数= 4的变量

27          Italy
49          Italy
66          Italy
2           Mexico
3           Mexico

同一国家/地区的行数超过10则为上限10的例外。

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

1 个答案:

答案 0 :(得分:1)

您可以在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 <>小提琴,用于显示代码正常工作(至少在某些情况下)。