Как сгруппировать с условиями последовательности в MySQL или Google Data Studio? - PullRequest
1 голос
/ 12 февраля 2020

У меня есть база данных посещаемости, в которой хранятся записи сотрудников, как показано ниже

Database structure

MySQL версия 5.7.26-log (нет отверстий в датах все даты существуют, но для удобства я удалил данные массовых дат из оператора вставки строки)

CREATE TABLE `stackoverflow` ( `id` int(9) NOT NULL DEFAULT '0', 
                               `Date` date NOT NULL, 
                               `EmpID` varchar(100) NOT NULL, 
                               `name` varchar(100) NOT NULL, 
                               `TeamName` varchar(100) NOT NULL, 
                               `Status` varchar(100) NOT NULL 
                             ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 

-- -- Dumping data for table `stackoverflow` -- 
INSERT INTO `stackoverflow` (`id`, `Date`, `EmpID`, `name`, `TeamName`, `Status`) 
VALUES 
(5, '2019-03-01', '303016', 'Yatendra Ranawat', 'Computer Vision', 'P'), 
(23, '2019-03-01', '303128', 'Nikhat Khan', 'Media - 3D Automation', 'P'), 
(193606, '2019-09-02', '303016', 'Yatendra Ranawat', 'Computer Vision', 'P'), 
(194631, '2019-09-03', '303016', 'Yatendra Ranawat', 'Noon', '-'), 
(222309, '2019-09-30', '303016', 'Yatendra Ranawat', 'Noon', '-'), 
(223336, '2019-10-01', '303016', 'Yatendra Ranawat', 'Noon-Indore', 'P'), 
(282742, '2019-11-28', '303016', 'Yatendra Ranawat', 'Noon-Indore', '-'), 
(283765, '2019-11-29', '303016', 'Yatendra Ranawat', 'Home Depot - Indore', 'P'), 
(303251, '2019-12-18', '303128', 'Nikhat Khan', 'Media - 3D Automation', '-'), 
(304275, '2019-12-19', '303128', 'Nikhat Khan', 'US Taxonomy - Indore', 'P'), 
(309393, '2019-12-24', '303128', 'Nikhat Khan', 'US Taxonomy - Indore', 'P'), 
(310416, '2019-12-25', '303128', 'Nikhat Khan', 'Media - 3D Automation', 'PH'), 
(354076, '2020-02-06', '303016', 'Yatendra Ranawat', 'Home Depot - Indore', '-'), 
(354088, '2020-02-06', '303128', 'Nikhat Khan', 'Media - 3D Automation', 'P');

Я использую Google Data Studio для создания отчета о длительности сотрудника в такой команде, как ниже

Employee Duration between team-1

Отлично работает, когда сотрудник переходит из одной команды в другую и не возвращается в команды, над которыми он ранее работал. Но когда сотрудник возвращается в команду, он ранее работал над ней, и он логизирует максимум и минимум enter image description here

Что мне нужно сделать в MySQL / Google Data Studio, чтобы получить результат как ниже с таблицей данных как выше?

or datastudio

Дайте мне знать, если вам требуются какие-либо подробности с моей стороны. Любые советы или рекомендации будут с благодарностью.

Ответы [ 2 ]

1 голос
/ 14 февраля 2020

Проверьте также следующий вариант, он быстрее:

SELECT EmpID, name, TeamName, startdate, MAX(enddate) enddate
FROM (
SELECT name,
       CASE WHEN EmpId = @id AND TeamName = @team 
            THEN @startdate
            ELSE @startdate := `Date` 
            END startdate,
       `Date` enddate,
       @id := EmpID EmpID,
       @team := TeamName TeamName
FROM stackoverflow, (SELECT @id := '', @team := '', @startdate := '') variables
ORDER BY EmpID, `Date`
) t
GROUP BY 1,2,3,4
ORDER BY 1,2,4,5;

fiddle

В моей системе с горячим кешем требуется 0.03 se c, тогда как запросы из предыдущего ответа - 25,39 сек c и 1 мин 54,79 сек c соответственно. В вашей системе с записями 220 Кб разница должна быть еще более впечатляющей.

1 голос
/ 12 февраля 2020

Тест

SELECT t4.EmpID, t4.name, t4.TeamName, MIN(t4.startdate) startdate, t4.enddate
FROM ( SELECT t1.EmpID, t1.name, t1.TeamName, t1.`Date` startdate, MAX(t2.`Date`) enddate
       FROM stackoverflow t1
       JOIN stackoverflow t2 ON t1.EmpID = t2.EmpID
                            AND t1.TeamName = t2.TeamName
                            AND t1.`Date` < t2.`Date`
       LEFT JOIN stackoverflow t3 ON t1.EmpID = t3.EmpID
                                 AND t1.TeamName != t3.TeamName
                                 AND t1.`Date` < t3.`Date`                          
                                 AND t3.`Date` < t2.`Date`
       WHERE t3.EmpId IS NULL
       GROUP BY 1,2,3,4 ) t4
GROUP BY 1,2,3,5
ORDER BY 1,2,4,5;

= этот запрос слишком медленный :( Сбой сервера при запуске таблицы, содержащей 222839 строк - Yatendra Ranawat

= @YatendraRanawat Convert ОСТАЛОСЬ ВСТУПИТЬ В НЕ СУЩЕСТВУЕТ ... - Акина

SELECT t4.EmpID, t4.name, t4.TeamName, MIN(t4.startdate) startdate, t4.enddate
FROM ( SELECT t1.EmpID, t1.name, t1.TeamName, t1.`Date` startdate, MAX(t2.`Date`) enddate
       FROM stackoverflow t1
       JOIN stackoverflow t2 ON t1.EmpID = t2.EmpID
                            AND t1.TeamName = t2.TeamName
                            AND t1.`Date` < t2.`Date`
       WHERE NOT EXISTS ( SELECT NULL
                          FROM stackoverflow t3 
                          WHERE t1.EmpID = t3.EmpID
                            AND t1.TeamName != t3.TeamName
                            AND t1.`Date` < t3.`Date`                          
                            AND t3.`Date` < t2.`Date` )
       GROUP BY 1,2,3,4 ) t4
GROUP BY 1,2,3,5
ORDER BY 1,2,4,5;

скрипка

...