【问题标题】:"Crosstab" Query Only Showing Most Recent Results“交叉表”查询仅显示最近的结果
【发布时间】:2020-03-05 11:53:27
【问题描述】:

我在 MySQL 中设置了一个查询,以返回带有月份作为列标题和培训师名称作为行标题的结果。我正在尝试按月确定培训师的 NPS 分数。当我运行查询时,它只显示他们有调查结果的上个月的结果。如何修复查询以显示他们每个月的调查结果?

基本表结构:

CREATE TABLE nh_survey (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  trainer TINYINT(1),
  trainer_nps TINYINT(1),
  class_Date DATE
);
INSERT INTO nh_survey
  (trainer,trainer_nps,class_Date)
VALUES
  ('''1''',' ''10''',' ''2019-10-21'''),
  ('''1''',' ''10''',' ''2019-10-21'''),
  ('''1''',' ''10''',' ''2019-10-21'''),
  ('''1''',' ''10''',' ''2019-10-21'''),
  ('''1''',' ''10''',' ''2019-10-25'''),
  ('''1''',' ''10''',' ''2019-10-21'''),
  ('''1''',' ''10''',' ''2019-10-21'''),
  ('''3''',' ''10''',' ''2019-10-14'''),
  ('''3''',' ''10''',' ''2019-10-14'''),
  ('''3''',' ''10''',' ''2019-10-14'''),
  ('''3''',' ''10''',' ''2019-10-14'''),
  ('''3''',' ''10''',' ''2019-10-14'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''7''',' ''2019-10-07'''),
  ('''16''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''9''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''15''',' ''10''',' ''2019-10-07'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-10-04'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''19''',' ''10''',' ''2019-09-30'''),
  ('''20''',' ''10''',' ''2019-09-23'''),
  ('''20''',' ''10''',' ''2019-09-23'''),
  ('''20''',' ''8''',' ''2019-09-23'''),
  ('''20''',' ''10''',' ''2019-09-23'''),
  ('''20''',' ''10''',' ''2019-09-23'''),
  ('''20''',' ''10''',' ''2019-09-23'''),
  ('''20''',' ''6''',' ''2019-09-23'''),
  ('''20''',' ''10''',' ''2019-09-23'''),
  ('''15''',' ''10''',' ''2019-09-26'''),
  ('''15''',' ''10''',' ''2019-08-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-20'''),
  ('''21''',' ''10''',' ''1992-10-07'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-16'''),
  ('''21''',' ''10''',' ''2019-09-20'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-10'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''19''',' ''10''',' ''2019-09-09'''),
  ('''20''',' ''10''',' ''2019-09-03'''),
  ('''20''',' ''10''',' ''2019-09-03'''),
  ('''20''',' ''10''',' ''2019-09-03'''),
  ('''20''',' ''10''',' ''2019-09-03'''),
  ('''20''',' ''10''',' ''2019-09-03'''),
  ('''20''',' ''10''',' ''2019-09-03'''),
  ('''20''',' ''10''',' ''2019-09-03'''),
  ('''20''',' ''10''',' ''2019-09-03'''),
  ('''16''',' ''10''',' ''2019-08-19'''),
  ('''20''',' ''10''',' ''2019-08-26'''),
  ('''20''',' ''10''',' ''2019-08-26'''),
  ('''20''',' ''10''',' ''2019-08-26'''),
  ('''20''',' ''10''',' ''2019-08-26'''),
  ('''20''',' ''10''',' ''2019-08-26'''),
  ('''20''',' ''10''',' ''2019-08-26'''),
  ('''15''',' ''10''',' ''2019-07-22'''),
  ('''16''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''8''',' ''2019-08-23'''),
  ('''16''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''10''',' ''2019-08-19'''),
  ('''15''',' ''10''',' ''2019-08-19'''),
  ('''1''',' ''10''',' ''2019-08-05'''),
  ('''1''',' ''10''',' ''2019-08-05''');

CREATE TABLE trainers (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  revname VARCHAR(255)
);
INSERT INTO trainers
  (id,revname)
VALUES
  (1,'Trainer 1'),
  (2,'Trainer 2'),
  (3,'Trainer 3'),
  (4,'Trainer 4'),
  (6,'Trainer 5'),
  (7,'Trainer 6'),
  (8,'Trainer 7'),
  (9,'Trainer 8'),
  (10,'Trainer 9'),
  (11,'Trainer 10'),
  (12,'Trainer 11'),
  (13,'Trainer 12'),
  (15,'Trainer 13'),
  (16,'Trainer 14'),
  (18,'Trainer 15'),
  (19,'Trainer 16'),
  (20,'Trainer 17'),
  (21,'Trainer 18'),
  (22,'Trainer 19'),
  (23,'Trainer 20'),
  (24,'Trainer 21');

这是查询:

select t1.revname AS 'Trainer',
 IF( MONTH( t2.class_date) =12, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Dec',
 IF( MONTH( t2.class_date) =1, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Jan',
 IF( MONTH( t2.class_date) =2, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Feb',
 IF( MONTH( t2.class_date) =3, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Mar',
 IF( MONTH( t2.class_date) =4, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Apr',
 IF( MONTH( t2.class_date) =5, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'May',
 IF( MONTH( t2.class_date) =6, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Jun',
 IF( MONTH( t2.class_date) =7, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Jul',
 IF( MONTH( t2.class_date) =8, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Aug',
 IF( MONTH( t2.class_date) =9, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Sep',
 IF( MONTH( t2.class_date) =10, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Oct',
 IF( MONTH( t2.class_date) =11, round(sum(t2.npscore)/count(t2.npscore)*100, 1 ),0)  AS 'Nov'
from
(select id, revname
from trainers
where id in(1,2,3,15,16,18,19,20,21)) t1
LEFT JOIN
(SELECT 
    trainer, 
    class_date,     
        CASE
                WHEN trainer_nps IN (9 , 10) THEN 1
                WHEN trainer_nps IN (7 , 8) THEN 0
                ELSE - 1
            END AS npscore            
    FROM
        nh_survey
        Where class_date between '2018-01-28' and '2019-11-30') t2 on t1.id = t2.trainer
group by t1.revname
order by t1.id ASC

如果我只按培训师分组,它只会给出培训师有调查结果的最后一个月。如果我将 class_date 添加到分组中,它会为每个培训师提供 12 行。

【问题讨论】:

标签: mysql pivot crosstab


【解决方案1】:

我不得不稍微熟悉一下您的数据。 有了这些数据

  CREATE TABLE nh_survey (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    trainer TINYINT(1),
    trainer_nps TINYINT(1),
    class_Date DATE
  );
  INSERT INTO nh_survey
    (trainer,trainer_nps,class_Date)
  VALUES
    ('1','10','2019-10-21'),
    ('1',' 10','2019-10-21'),
    ('1','10','2019-10-21'),
    ('1','10','2019-10-21'),
    ('1','10','2019-10-25'),
    ('1','10','2019-10-21'),
    ('1','10','2019-10-21'),
    ('3','10','2019-10-14'),
    ('3','10','2019-10-14'),
    ('3','10','2019-10-14'),
    ('3','10','2019-10-14'),
    ('3','10','2019-10-14'),
    ('15','10','2019-10-07'),
    ('15','10','2019-10-07'),
    ('15','10','2019-10-07'),
    ('15','10','2019-10-07'),
    ('15','10','2019-10-07'),
    ('15','7','2019-10-07'),
    ('16','10','2019-10-07'),
    ('15','10','2019-10-07'),
    ('15','10','2019-10-07'),
    ('15','9','2019-10-07'),
    ('15','10','2019-10-07'),
    ('15','10','2019-10-07'),
    ('15','10','2019-10-07'),
    ('19','10','2019-09-30'),
    ('19','10','2019-09-30'),
    ('19','10','2019-09-30'),
    ('19','10','2019-09-30'),
    ('19','10','2019-09-30'),
    ('19','10','2019-09-30'),
    ('19','10','2019-09-30'),
    ('19','10','2019-09-30'),
    ('19','10','2019-10-04'),
    ('19','10','2019-09-30'),
    ('19','10','2019-09-30'),
    ('20','10','2019-09-23'),
    ('20','10','2019-09-23'),
    ('20','8','2019-09-23'),
    ('20','10','2019-09-23'),
    ('20','10','2019-09-23'),
    ('20','10','2019-09-23'),
    ('20','6','2019-09-23'),
    ('20','10','2019-09-23'),
    ('15','10','2019-09-26'),
    ('15','10','2019-08-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-20'),
    ('21','10','1992-10-07'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-16'),
    ('21','10','2019-09-20'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-10'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('19','10','2019-09-09'),
    ('20','10','2019-09-03'),
    ('20','10','2019-09-03'),
    ('20','10','2019-09-03'),
    ('20','10','2019-09-03'),
    ('20','10','2019-09-03'),
    ('20','10','2019-09-03'),
    ('20','10','2019-09-03'),
    ('20','10','2019-09-03'),
    ('16','10','2019-08-19'),
    ('20','10','2019-08-26'),
    ('20','10','2019-08-26'),
    ('20','10','2019-08-26'),
    ('20','10','2019-08-26'),
    ('20','10','2019-08-26'),
    ('20','10','2019-08-26'),
    ('15','10','2019-07-22'),
    ('16','10','2019-08-19'),
    ('15','8','2019-08-23'),
    ('16','10','2019-08-19'),
    ('15','10','2019-08-19'),
    ('15','10','2019-08-19'),
    ('15','10','2019-08-19'),
    ('15','10','2019-08-19'),
    ('15','10','2019-08-19'),
    ('15','10','2019-08-19'),
    ('15','10','2019-08-19'),
    ('15','10','2019-08-19'),
    ('1','10','2019-08-05'),
    ('1','10','2019-08-05');

  CREATE TABLE trainers (
    id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
    revname VARCHAR(255)
  );
  INSERT INTO trainers
    (id,revname)
  VALUES
    (1,'Trainer 1'),
    (2,'Trainer 2'),
    (3,'Trainer 3'),
    (4,'Trainer 4'),
    (6,'Trainer 5'),
    (7,'Trainer 6'),
    (8,'Trainer 7'),
    (9,'Trainer 8'),
    (10,'Trainer 9'),
    (11,'Trainer 10'),
    (12,'Trainer 11'),
    (13,'Trainer 12'),
    (15,'Trainer 13'),
    (16,'Trainer 14'),
    (18,'Trainer 15'),
    (19,'Trainer 16'),
    (20,'Trainer 17'),
    (21,'Trainer 18'),
    (22,'Trainer 19'),
    (23,'Trainer 20'),
    (24,'Trainer 21');

这个选择语句

  SELECT MAX(Trainer) Trainer
   ,SUM(IF( monthnb =1, score, 0 ))  AS 'Jan'
   ,SUM(IF( monthnb =2, score,0 ))  AS 'Feb'
   ,SUM(IF( monthnb =3, score,0 ))  AS 'Mar'
   ,SUM(IF( monthnb =4, score, 0 ))  AS 'Apr'
   ,SUM(IF( monthnb =5, score,0 ))  AS 'May'
   ,SUM(IF( monthnb =6, score,0 ))  AS 'Jun'
   ,SUM(IF( monthnb =7, score, 0 ))  AS 'Jul'
   ,SUM(IF( monthnb =8, score,0 ))  AS 'Aug'
   ,SUM( IF( monthnb =9, score,0 ))  AS 'Sep'
   ,SUM(IF( monthnb =10, score, 0 ))  AS 'Oct'
   ,SUM(IF( monthnb =11, score,0 ))  AS 'Nov'
   ,SUM(IF( monthnb =12, score,0 ))  AS 'Dec'
  FROM
  (
    SELECT id,revname AS 'Trainer'
  ,MONTH(class_date)  monthnb
  ,round(sum(npscore)/count(npscore)*100) score
  FROM
  (select id, revname
  from trainers
  where id in(1,2,3,15,16,18,19,20,21)) t1
  LEFT JOIN
  (SELECT 
      trainer, 
      class_date,     
          CASE
                  WHEN trainer_nps IN (9 , 10) THEN 1
                  WHEN trainer_nps IN (7 , 8) THEN 0
                  ELSE - 1
              END AS npscore            
      FROM
          nh_survey
          Where class_date between '2018-01-28' and '2019-11-30') t2 on t1.id = t2.trainer    
   GROUP BY id,revname, MONTH(class_date) 
   ) tr1
GROUP BY id;

会给出以下结果

培训师 |一月 |二月 |三月 |四月 |五月 |君 |七月 |八月 |九月 |十月 |十一月 |十二月 :----------- | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: 培训师 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 0 | 100 | 0 | 0 培训师 3 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 0 | 0 培训师 13 | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 90 | 100 | 92 | 0 | 0 培训师 14 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 0 | 100 | 0 | 0 培训师 16 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 100 | 0 | 0 培训师 17 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 81 | 0 | 0 | 0 培训师 18 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 100 | 0 | 0 | 0 教练2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 培训师 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0

参见 dbfiddle 示例 https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ac5c062b818171cf47ddb16bec81ff99

【讨论】:

  • 谢谢nbk。这正是我所需要的。我必须研究它以了解它在做什么,但它给了我我想要的东西。太感谢了!我赞成你的答案,但没有足够的分数来显示它。
猜你喜欢
  • 2016-04-30
  • 1970-01-01
  • 1970-01-01
  • 2011-04-23
  • 2020-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多