Mysql在数据透视视图中显示数据

时间:2013-04-15 09:45:29

标签: mysql select pivot mysql-workbench

对不起伙计们,因为面对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

1 个答案:

答案 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;

请参阅SQL Fiddle with Demo

我编写了一个硬编码版本,因此您可以看到如何编写代码,但如果您将数据基于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 |

如果这不是您想要的结果,那么您将需要进一步解释您的需求。

相关问题