【问题标题】:Using MySQL Pivot Table Queries for a Monthly Attendance Report使用 MySQL 数据透视表查询生成月度考勤报告
【发布时间】:2011-07-19 08:18:53
【问题描述】:

我使用数据透视查询来获取月度报告..

我的桌子是这样的:

CREATE TABLE IF NOT EXISTS `attendance` (
  `empID` int(11) NOT NULL,
  `date` date NOT NULL,
  `deptID` int(11) NOT NULL,
  `attStatus` varchar(3) NOT NULL,
  PRIMARY KEY (`empID`,`date`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;

对于月度考勤报告,我使用了这个查询:

SELECT empID,
  GROUP_CONCAT(if(DAY(`date`) = 1, `attStatus`, NULL)) AS 'day1', 
  GROUP_CONCAT(if(DAY(`date`) = 2, `attStatus`, NULL)) AS 'day2', 
  GROUP_CONCAT(if(DAY(`date`) = 3, `attStatus`, NULL)) AS 'day3', 
  GROUP_CONCAT(if(DAY(`date`) = 4, `attStatus`, NULL)) AS 'day4', 
  GROUP_CONCAT(if(DAY(`date`) = 5, `attStatus`, NULL)) AS 'day5', 
  GROUP_CONCAT(if(DAY(`date`) = 6, `attStatus`, NULL)) AS 'day6', 
  GROUP_CONCAT(if(DAY(`date`) = 7, `attStatus`, NULL)) AS 'day7', 
  GROUP_CONCAT(if(DAY(`date`) = 8, `attStatus`, NULL)) AS 'day8', 
  GROUP_CONCAT(if(DAY(`date`) = 9, `attStatus`, NULL)) AS 'day9', 
  GROUP_CONCAT(if(DAY(`date`) = 10, `attStatus`, NULL)) AS 'day10',
  GROUP_CONCAT(if(DAY(`date`) = 11, `attStatus`, NULL)) AS 'day11', 
  GROUP_CONCAT(if(DAY(`date`) = 12, `attStatus`, NULL)) AS 'day12', 
  GROUP_CONCAT(if(DAY(`date`) = 13, `attStatus`, NULL)) AS 'day13', 
  GROUP_CONCAT(if(DAY(`date`) = 14, `attStatus`, NULL)) AS 'day14', 
  GROUP_CONCAT(if(DAY(`date`) = 15, `attStatus`, NULL)) AS 'day15', 
  GROUP_CONCAT(if(DAY(`date`) = 16, `attStatus`, NULL)) AS 'day16', 
  GROUP_CONCAT(if(DAY(`date`) = 17, `attStatus`, NULL)) AS 'day17', 
  GROUP_CONCAT(if(DAY(`date`) = 18, `attStatus`, NULL)) AS 'day18', 
  GROUP_CONCAT(if(DAY(`date`) = 19, `attStatus`, NULL)) AS 'day19', 
  GROUP_CONCAT(if(DAY(`date`) = 20, `attStatus`, NULL)) AS 'day20', 
  GROUP_CONCAT(if(DAY(`date`) = 21, `attStatus`, NULL)) AS 'day21', 
  GROUP_CONCAT(if(DAY(`date`) = 22, `attStatus`, NULL)) AS 'day22', 
  GROUP_CONCAT(if(DAY(`date`) = 23, `attStatus`, NULL)) AS 'day23', 
  GROUP_CONCAT(if(DAY(`date`) = 24, `attStatus`, NULL)) AS 'day24', 
  GROUP_CONCAT(if(DAY(`date`) = 25, `attStatus`, NULL)) AS 'day25', 
  GROUP_CONCAT(if(DAY(`date`) = 26, `attStatus`, NULL)) AS 'day26', 
  GROUP_CONCAT(if(DAY(`date`) = 27, `attStatus`, NULL)) AS 'day27', 
  GROUP_CONCAT(if(DAY(`date`) = 28, `attStatus`, NULL)) AS 'day28', 
  GROUP_CONCAT(if(DAY(`date`) = 29, `attStatus`, NULL)) AS 'day29', 
  GROUP_CONCAT(if(DAY(`date`) = 30, `attStatus`, NULL)) AS 'day30',  
  GROUP_CONCAT(if(DAY(`date`) = 31, `attStatus`, NULL)) AS 'day31', 
  COUNT(if(`attStatus`='P', `attStatus`, NULL)) AS 'totalP'
FROM `attendance`
WHERE deptID=1 AND `date` BETWEEN '2011-07-01' AND '2011-07-31'
GROUP BY empID

所以我的问题是,这个查询是不是太长了? 此查询是否有任何替代方法来显示每月出勤报告?

如果此查询正常,那么对于其中有 30 天的月份,将显示 31 天的结果。有什么解决办法吗?

更新:

这是一个屏幕截图,解释了我想要什么类型的报告:

【问题讨论】:

标签: mysql pivot-table


【解决方案1】:

不知道您的原始查询是否可行,但这样的事情会更简单:

select DAY(date),count(*) from attendance where MONTH(date) = 2 group by DAY(date);

那应该会在 2 月获得出席人数。输出将是:

+-----------+----------+
| DAY(date) | count(*) |
+-----------+----------+
|      18   |        1 |
|      19   |        2 |
+-----------+----------+

【讨论】:

  • 实际上我忘了指定“attStatus”列可以包含值“P”、“A”、“WO”、“M”等,我想在报告中显示每一天的状态..
  • 你想如何显示每天的attStatus状态?每个与会者都有一个,并且您每天对与会者统计数据进行分组?如果您在问题中发布预期的报告输出会很好
  • 我已经发布了更新。我想使用这种报告..这个查询工作正常..但是可以使用任何替代的短查询吗??
【解决方案2】:

首先,创建一个帮助表:

CREATE TABLE days
( d TINYINT PRIMARY KEY
) ;

INSERT INTO days
VALUES
(0), (1), (2), ..., (31) ;

那你可以试试这个。它会返回比您的查询更少的列:

SELECT 
    a.empID
  , GROUP_CONCAT( CASE WHEN a.attStatus IS NULL
                           THEN 'N'
                           ELSE a.attStatus
                  END
                  ORDER BY dates.dateCheck)
    AS days
  , COUNT( CASE WHEN a.attStatus='P' THEN 1 END )
    AS totalP
FROM
    ( SELECT monthStart + INTERVAL d DAY
             AS dateCheck
      FROM days
        CROSS JOIN
          ( SELECT '2011-07-01' AS monthStart 
          ) AS m 
      WHERE MONTH(monthStart + INTERVAL d DAY) = MONTH(monthStart)
    ) AS dates
  LEFT JOIN attendance AS a
    ON a.`date` = dates.dateCheck
WHERE a.deptID = 1 
GROUP BY a.empID

【讨论】:

    猜你喜欢
    • 2016-07-20
    • 2017-02-10
    • 1970-01-01
    • 2012-04-21
    • 2019-01-04
    • 2012-02-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多