【问题标题】:MySQL query to create summary row for query with HAVING and LIMIT clausesMySQL 查询为具有 HAVING 和 LIMIT 子句的查询创建摘要行
【发布时间】:2017-02-08 14:29:19
【问题描述】:

我在弄清楚如何编写可以为使用 HAVING 和 LIMIT 子句的查询创建摘要行的 MySQL 查询时遇到问题。这是一些示例数据,可以重新创建我的问题..

样本表

CREATE TABLE `user` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `logins` int(10) unsigned DEFAULT NULL,
  `date` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

样本数据

INSERT INTO `user` (`id`, `logins`, `date`)
VALUES
    (1,1,'2016-09-25'),
    (2,1,'2016-09-25'),
    (3,2,'2016-09-26'),
    (4,2,'2016-09-26'),
    (5,3,'2016-09-27'),
    (6,3,'2016-09-27'),
    (7,4,'2016-09-28'),
    (8,4,'2016-09-28'),
    (9,5,'2016-09-29'),
    (10,5,'2016-09-29');

这是我的一个显示完整结果的基本查询。

mysql> select `date`, sum(`logins`) `logins` from `user` group by `date`;
+------------+--------+
| date       | logins |
+------------+--------+
| 2016-09-25 |      2 |
| 2016-09-26 |      4 |
| 2016-09-27 |      6 |
| 2016-09-28 |      8 |
| 2016-09-29 |     10 |
+------------+--------+

虽然是对的,但从中得到一个摘要行没有问题..

mysql> select sum(`logins`) `logins` from `user`;
+--------+
| logins |
+--------+
|     30 |
+--------+

但是,如果我想从下面的查询中构建一个摘要行怎么办?在此示例中,我添加了 HAVING 和 LIMIT 子句,用于模拟非常大的数据集。此查询中的 HAVING 子句表示用户可以在界面中提供的过滤器中更改的最大数量。限制 0,2 表示结果的第 1 页(在这种情况下为 3 页:0,2;2,4;4,6)。这些查询是分页系统的一部分,用于一次按 X、X 数量显示结果。因此查询中 LIMIT 子句的原因..

mysql> select `date`, sum(`logins`) `logins` from `user` group by `date` having `logins` <= 8 limit 0, 2;
+------------+--------+
| date       | logins |
+------------+--------+
| 2016-09-25 |      2 |
| 2016-09-26 |      4 |
+------------+--------+

在这种情况下,我需要的上述结果集的摘要查询应该总计 6 次登录。我将如何构建一个查询来做这样的事情?

现在我不能简单地循环查询结果(客户端或服务器端)来统计总数,因为 html 表(服务器端生成)只显示结果的第一页,并且只会统计该特定页面上显示的计数。我需要显示一个汇总行,其中包含表分页所有页面的完整数据集的计数,如果这有任何意义的话..

更新

这是一种期望结果的样本..

+------------+--------+
| date       | logins |
+------------+--------+
| 2016-09-25 |      2 |
| 2016-09-26 |      4 |
+------------+--------+
| TOTAL      |     20 | <-- JUST NEED A QUERY TO PRODUCE THIS NUMBER SOME HOW..
+------------+--------+

对不起各位.. 我的意思是说 20 应该是数字,而不是 6.. 因为使用 HAVING 过滤器的完整结果集是这样的:

mysql> select `date`, sum(`logins`) `logins` from `user` group by `date` having `logins` <= 8;
+------------+--------+
| date       | logins |
+------------+--------+
| 2016-09-25 |      2 |
| 2016-09-26 |      4 |
| 2016-09-27 |      6 |
| 2016-09-28 |      8 |
+------------+--------+

对不起!

这几乎就像我需要这样的查询(没有分组):

select `date`, sum(`logins`) `logins` from `user` having `logins` <= 8

但显然这不起作用..

最终更新

这是我的 20 个基于 @Shadow 的答案,下面是一个非常简单的例子,但最终让我得到了我需要的答案:

mysql> select sum(`logins`) `logins` from (select `date`, sum(`logins`) `logins` from `user` group by `date` having `logins` <= 8) t;
+--------+
| logins |
+--------+
|     20 |
+--------+

【问题讨论】:

  • 这看起来很像你想要的!你能显示所需的输出吗
  • 我需要一个查询来显示 6 个登录作为最后一个查询的摘要行。

标签: mysql


【解决方案1】:

需要在应用了 have 和 limit 子句后进行总结。在显示数字时在表示层中执行此操作,或者您必须将第二个查询作为 sql 中的子查询并在外部查询中进行求和。

select sum(logins) as logins from
    (select `date`, sum(`logins`) `logins` from `user` group by `date` having `logins` <= 8 limit 0, 2) t

【讨论】:

  • 嘿现在..这可能正是我正在寻找的!我取消了限制并得到了我需要的东西 (20)。去试试看。
  • 好吧,根据这个答案,我让它正常工作,非常感谢@Shadow!
【解决方案2】:

您可以使用CROSS JOIN 将总结果包含到您的查询中:

select u.`date`, 
       sum(u.`logins`) `logins`,
       t.`total_logins` 
from `user` as u  
cross join (select sum(`logins`) `total_logins` from `user`) as t
group by u.`date` 
having `logins` <= 8 limit 0, 2;

Demo here

编辑:

您可以使用下面更复杂的查询来获得所需的结果:

select `date`, `logins`
from (
  select `date`, `logins`, @rn := @rn + 1  as rn
  from (
     select case when `date` is null then 'Total' else `date` end as `date`, 
            sum(`logins`) as `logins`
     from (
        select `date`, sum(`logins`) `logins` 
        from `user` 
        group by `date` 
        having `logins` <= 8) as t
     group by `date` with rollup ) as s
  cross join (select @rn := 0) as v       
  order by case when `date` = 'Total' then 1 else 0 end,
           `date`) as x
where x.rn <= 2 or x.`date` = 'Total'  

Demo here

【讨论】:

  • 在上面最后一个查询的结果中只有 6 个。这个查询给了我 30 个 ..
  • @Rick 你说:我需要显示一个包含完整数据集计数的摘要行所以你需要显示 total 行数?
  • “在这种情况下,我对上述结果集需要的摘要查询应该有 6 次登录。我将如何构建一个查询来做这样的事情?”
  • 我在上面做了几次更新。我在 6 上弄错了。应该是 20。
  • @Giorgos 好吧,这确实工作得很好,但是对于我的脚本来说它有点过于复杂,因为查询是动态构建的,并且有许多过滤器和许多可以连接的表等等。但是非常感谢很多建议!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-26
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
相关资源
最近更新 更多