使用大小写的类似于枢轴的SELECT语句的可能的查询缩短

时间:2013-12-13 10:19:17

标签: mysql

我有一个'形成'表(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  |

1 个答案:

答案 0 :(得分:0)

首先,您的查询的简化版本可能看起来像

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;

这是 SQLFiddle 演示


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

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();

这是 SQLFiddle 演示