Запрос "Crosstab" только показывает самые последние результаты - PullRequest
0 голосов
/ 08 ноября 2019

У меня в 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 строк для каждого тренера.

1 Ответ

0 голосов
/ 09 ноября 2019

Мне пришлось немного узнать ваши данные. С этими данными

  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;

даст следующий результат

Trainer      | Jan | Feb | Mar | Apr | May | Jun | Jul | Aug | Sep | Oct | Nov | Dec
:----------- | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --: | --:
Trainer 1    |   0 |   0 |   0 |   0 |   0 |   0 |   0 | 100 |   0 | 100 |   0 |   0
Trainer 3    |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 | 100 |   0 |   0
Trainer 13   |   0 |   0 |   0 |   0 |   0 |   0 | 100 |  90 | 100 |  92 |   0 |   0
Trainer 14   |   0 |   0 |   0 |   0 |   0 |   0 |   0 | 100 |   0 | 100 |   0 |   0
Trainer 16   |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 | 100 | 100 |   0 |   0
Trainer 17   |   0 |   0 |   0 |   0 |   0 |   0 |   0 | 100 |  81 |   0 |   0 |   0
Trainer 18   |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 | 100 |   0 |   0 |   0
Trainer 2    |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0
Trainer 15   |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0 |   0

См. Пример dbfiddle https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=ac5c062b818171cf47ddb16bec81ff99

...