2016-09-30 123 views
2

我在解决如何编写能够为使用HAVING和LIMIT子句的查询创建摘要行的MySQL查询有问题。下面是一些示例数据和这样的重现我的问题..MySQL查询使用HAVING和LIMIT子句创建查询的摘要行

样品表

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数量的结果。因此,对于在查询中的限制条款的原因..

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表(服务器端生成)只显示结果的第一页,并且只会计数显示在该特定页面上的计数。我需要以显示与完整的数据集跨表分页的所有页面,如果让任何意义的计数摘要行..

UPDATE

这是一种理想的结果的样本..

+------------+--------+ 
| 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 | 
+------------+--------+ 

SORRY!

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

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

但显然这并不工作..

最后更新

那么这里是我20基于客@低于阴影的回答是一个很简单的例子,但最终导致我我所需要的答案:

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

看起来很像你想要的东西!你能显示所需的输出 – e4c5

+0

我需要一个查询来显示6登录为最后一次查询的摘要行。 – Rick

回答

2

你需要做后的总结有和限制条款适用。当你显示数字时你可以在表示层做这些事情,或者你必须在sql中有第二个查询作为子查询,并且在外部查询中完成总和。

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

嘿,现在..这可能正是我要找的!我删除了限制,并得到我需要的(20)。要尝试一下,看看。 – Rick

+0

嗯,我得到它正常工作基于这个答案,所以非常感谢你@Shadow! – Rick

0

可以使用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

+0

虽然在上面的最后一个查询的结果中只有6个..这个查询给了我30 .. – Rick

+0

@Rick你说:*我需要显示一个带有完整数据集计数的汇总行*所以你需要显示*总数*行数? –

+0

“在这种情况下,我需要上述结果集的摘要查询应该合计6个登录名,我该如何构建一个查询来执行此类操作?” – Shadow