Mysql 使用case对类似pivot的SELECT语句进行可能的查询缩短

Mysql 使用case对类似pivot的SELECT语句进行可能的查询缩短,mysql,Mysql,我有一个“formaction”表id、输入时间、用户名、操作,目的是记录所有用户的操作,现在只需登录、注销即可。我创建了以下查询,以了解员工登录程序的次数,其输出正是我所期望的 但是,我的雇主至少有几十名员工在使用这个程序。像我那样一个接一个地打字可不是件容易的事。是否可以使用“主员工”表id、用户名和密码进行联接 谢谢你 SELECT a.date,SUM(a.name1) name1, SUM(a.name2) name2,SUM(a.name3) name3,SUM(a.name4) n

我有一个“formaction”表id、输入时间、用户名、操作,目的是记录所有用户的操作,现在只需登录、注销即可。我创建了以下查询,以了解员工登录程序的次数,其输出正是我所期望的

但是,我的雇主至少有几十名员工在使用这个程序。像我那样一个接一个地打字可不是件容易的事。是否可以使用“主员工”表id、用户名和密码进行联接

谢谢你

SELECT a.date,SUM(a.name1) name1, SUM(a.name2) name2,SUM(a.name3) name3,SUM(a.name4) name4,
       SUM(a.name5) name5,SUM(a.name6) name6,SUM(a.name7) name7, SUM(a.name8) name8, SUM(a.name9) name9
FROM (
  SELECT 
    date(f.inputtime) date,
    case when users = "name1" then 1 end AS name1,
    case when users = "name2" then 1 end AS name2,
    case when users = "name3" then 1 end AS name3,
    case when users = "name4" then 1 end AS name4,
    case when users = "name5" then 1 end AS name5,
    case when users = "name6" then 1 end AS name6,
    case when users = "name7" then 1 end AS name7,
    case when users = "name8" then 1 end AS name8,
    case when users = "name9" then 1 end AS name9
  FROM formaction f WHERE ACTION = 'sign in'  ORDER BY date(inputtime) DESC)a  
GROUP BY  a.date 
它的输出类似于这样的枢轴:

date  |name1|name2|name3|name4|name5|name6|name7|name8|name9
1dec13|  1  |  2  |  1  |  7  |  3  |null |  1  |null |  2  |
2dec13|  1  |  3  |  1  |  5  |  1  |  1  |null |  3  |  1  |

首先,查询的简化版本可能如下所示

SELECT DATE(inputtime) date, 
       SUM(username = 'user1') `user1`,
       SUM(username = 'user2') `user2`,
       ... 
  FROM formaction 
 WHERE action = 'sign in' 
 GROUP BY DATE(inputtime)
现在,为了能够从employee表中动态地引入用户名,您可以使用动态SQL

SET @sql = NULL;

SELECT GROUP_CONCAT(CONCAT('SUM(username = ''', username, ''') `', username, '`'))
  INTO @sql
  FROM employee;

SET @sql = CONCAT('SELECT DATE(inputtime) date, ', @sql,
                  '  FROM formaction
                    WHERE action = ''sign in''
                    GROUP BY DATE(inputtime)');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
这是演示

为了简化调用端的工作,可以将其包装到存储过程中

DELIMITER $$
CREATE PROCEDURE report()
BEGIN
  SET @sql = NULL;

  SELECT GROUP_CONCAT(CONCAT('SUM(username = ''', username, ''') `', username, '`'))
    INTO @sql
    FROM employee;

  SET @sql = CONCAT('SELECT DATE(inputtime) date, ', @sql,
                    '  FROM formaction
                      WHERE action = ''sign in''
                      GROUP BY DATE(inputtime)');

  PREPARE stmt FROM @sql;
  EXECUTE stmt;
  DEALLOCATE PREPARE stmt;
END$$
DELIMITER ;
然后使用它

CALL report();

这是演示

它有用吗?你的问题需要更多的帮助吗?抱歉,我花了很长时间才回答。它起作用了!太棒了!我设法每月自动计算公司所有员工的工资。由银行导出自动工资单的数据。简化人力资源工作很多。不管有多少人来来去去,代码都能完美地处理它。谢谢你,伙计: