对不起伙计们,因为面对sqlfiddle.com的一些问题而无法生成小提琴
我在mysql数据库中有一个表,如下所示:
Username mailtime mailid
User4 3/23/2013 10:26 4473
User1 4/6/2013 16:13 10934
User4 4/6/2013 17:17 10957
User1 4/6/2013 23:56 11092
User2 4/7/2013 11:58 11187
User1 4/7/2013 12:06 11190
User4 4/7/2013 13:11 11216
User4 4/7/2013 13:14 11217
User1 4/7/2013 14:40 11245
User5 4/7/2013 15:52 11259
User1 4/7/2013 18:12 11303
User5 4/7/2013 19:56 11323
User1 4/7/2013 22:52 11358
User4 4/8/2013 11:13 11465
User1 4/8/2013 11:20 11475
User1 4/8/2013 11:35 11491
User4 4/8/2013 12:10 11511
User4 4/8/2013 12:38 11532
User4 4/8/2013 12:51 11540
User4 4/8/2013 13:06 11551
User1 4/8/2013 13:09 11552
User4 4/8/2013 13:15 11560
User1 4/8/2013 13:24 11572
User1 4/8/2013 14:01 11614
User4 4/8/2013 14:27 11640
User1 4/8/2013 15:41 11700
User5 4/8/2013 16:04 11730
User1 4/8/2013 17:40 11814
User4 4/9/2013 11:16 12117
User1 4/9/2013 12:41 12198
User1 4/9/2013 12:59 12209
User4 4/9/2013 13:58 12243
User4 4/9/2013 14:05 12250
User1 4/9/2013 14:15 12256
User4 4/9/2013 16:51 12351
User1 4/9/2013 17:33 12397
User1 4/9/2013 19:01 12455
User4 4/9/2013 19:15 12463
User5 4/9/2013 20:59 12517
User1 4/9/2013 21:26 12530
User1 4/9/2013 22:46 12561
User1 4/10/2013 1:01 12595
User1 4/10/2013 8:42 12631
User1 4/10/2013 10:18 12663
User1 4/10/2013 11:21 12697
User3 4/10/2013 11:27 12701
User4 4/10/2013 11:34 12705
User1 4/10/2013 15:26 12856
User4 4/10/2013 16:51 12909
User2 4/10/2013 16:53 12913
我需要的输出如下:
Username < 5 days 6-Apr 7-Apr 8-Apr 9-Apr 10-Apr Grand Total
User1
User2
User3
User4
User5
Grand Total
不知道该怎么做。
最大邮件时间显示在前一列的第二列和前一天中,并且&lt;所有其他日子累计5天
EDIT ::
所需的数据是mailid的数量
列&lt; 5天,6月4日,7月4日,8月4日,9月4日和4月4日是来自mailtime Column的列。如果列中的最大日期是3月25日,则列应为&lt; 5天,20-Mar,21-Mar,22-Mar,23-Mar,3月24日和25-Mar
答案 0 :(得分:1)
您对所需结果的描述并不完全清楚,但似乎您可以使用以下内容来获得结果。这将获取前5天每个用户名的总行数(基于最大日期)以及每个用户在此5天之前的总行数:
select
coalesce(username, 'Grand Total') username,
max(`< 5 days`) `< 5 days`,
sum(case when maildate = '6-Apr' then 1 else 0 end) `6-Apr`,
sum(case when maildate = '7-Apr' then 1 else 0 end) `7-Apr`,
sum(case when maildate = '8-Apr' then 1 else 0 end) `8-Apr`,
sum(case when maildate = '9-Apr' then 1 else 0 end) `9-Apr`,
sum(case when maildate = '10-Apr' then 1 else 0 end) `10-Apr`,
count(*) GrandTotal
from
(
select c.username,
date_format(c.mailtime, '%e-%b') maildate,
coalesce(o.`< 5 days`, 0) `< 5 days`
from yt c
left join
(
select username,
count(*) `< 5 days`
from yt
where mailtime <= (select date_sub(max(mailtime), interval 4 DAY)
from yt)
) o
on c.username = o.username
where c.mailtime >= (select date_sub(max(mailtime), interval 4 DAY)
from yt)
) d
group by username with rollup;
我编写了一个硬编码版本,因此您可以看到如何编写代码,但如果您将数据基于max(mailtime)
,那么您很可能希望使用动态SQL来获取结果。您可以使用预准备语句生成将要执行的SQL字符串:
SET @sql = NULL;
SELECT
GROUP_CONCAT(DISTINCT
CONCAT(
'sum(CASE WHEN maildate = ''',
date_format(mailtime, '%e-%b'),
''' THEN 1 else 0 END) AS `',
date_format(mailtime, '%e-%b'), '`'
)
) INTO @sql
FROM yt
WHERE mailtime >= (select date_sub(max(mailtime), interval 4 DAY)
from yt);
SET @sql
= CONCAT('SELECT coalesce(username, ''Grand Total'') username,
max(`< 5 days`) `< 5 days`, ', @sql, ' ,
count(*) GrandTotal
from
(
select c.username,
date_format(c.mailtime, ''%e-%b'') maildate,
coalesce(o.`< 5 days`, 0) `< 5 days`
from yt c
left join
(
select username,
count(*) `< 5 days`
from yt
where mailtime <= (select date_sub(max(mailtime), interval 4 DAY)
from yt)
) o
on c.username = o.username
where c.mailtime >= (select date_sub(max(mailtime), interval 4 DAY)
from yt)
) d
group by username with rollup ');
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
见SQL Fiddle with Demo。两个查询都给出了结果:
| USERNAME | < 5 DAYS | 6-APR | 7-APR | 8-APR | 9-APR | 10-APR | GRANDTOTAL |
--------------------------------------------------------------------------------
| User1 | 0 | 1 | 4 | 7 | 7 | 5 | 24 |
| User2 | 0 | 0 | 1 | 0 | 0 | 1 | 2 |
| User3 | 0 | 0 | 0 | 0 | 0 | 1 | 1 |
| User4 | 2 | 1 | 2 | 7 | 5 | 2 | 17 |
| User5 | 0 | 0 | 2 | 1 | 1 | 0 | 4 |
| Grand Total | 2 | 2 | 9 | 15 | 13 | 9 | 48 |
如果这不是您想要的结果,那么您将需要进一步解释您的需求。