我如何按类别计算特定月份的状态 changed/updated
how can i count status changed/updated by categories for a specific month
我想按类别名称统计给定月份的项目状态updates/changes
我有一个类别(类别列表)、投资(投资者投资列表,包括来自类别的 category_id)、状态 table,其名称包含实施前、实施和运营状态。
一个项目包含项目 ID、名称、开始日期字段。
status 和 projects 都有多对多的关系,叫做 project_status table contains project_id, status_id, date_of_progress.
我想按类别名称
统计本月内拥有 update/change 个 status_id 的所有项目
从实施前到实施
从实施到运营
从实施前到运营
CREATE TABLE `categories` (
`cat_id` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`description` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `categories` (`cat_id`, `name`, `description`) VALUES
(1, 'agriculture', ''),
(2, 'manufactures ', ''),
(3, 'Technology', ''),
(4, 'services', '');
CREATE TABLE `investments` (
`investment_id` int(11) NOT NULL,
`investment_name` varchar(100) NOT NULL,
`cat_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `investments` (`investment_id`, `investment_name`, `cat_id`) VALUES
(1, 'Company A', 3),
(2, 'Company B', 4),
(3, 'Company C', 1),
(4, 'Company D', 2),
(5, 'Company E', 3),
(6, 'Company F', 4),
(7, 'Company G', 1),
(8, 'Company H', 2);
CREATE TABLE `status` (
`status_id` int(11) NOT NULL,
`status_name` varchar(30) NOT NULL,
`description` varchar(255) DEFAULT NULL,
`status_name_tg` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `status` (`status_id`, `status_name`, `description`, `status_name_tg`) VALUES
(1, 'Pre Implementation', 'Operational', 'Pre Implementation'),
(2, 'Implementation', NULL, 'Implementation'),
(3, 'Operational', NULL, 'Operational'),
(4, 'Inactive', NULL, 'Inactive'),
(5, 'Cancellation', NULL, 'Cancellation');
CREATE TABLE `project_status` (
`project_status_id` int(11) NOT NULL,
`status_id` int(11) NOT NULL,
`time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`project_id` int(11) NOT NULL,
`reason_for_cancellation` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `project_status` (`project_status_id`, `status_id`, `time`, `project_id`, `reason_for_cancellation`) VALUES
(1, 1, '2019-02-24 21:51:50', 1, NULL),
(2, 2, '2019-03-26 21:52:57', 1, NULL),
(3, 1, '2019-04-30 21:57:57', 2, NULL),
(4, 1, '2019-05-26 22:04:08', 3, NULL),
(5, 3, '2019-08-24 22:06:36', 1, NULL),
(6, 2, '2019-08-11 22:07:05', 3, NULL),
(8, 1, '2019-08-01 00:14:41', 6, NULL),
(9, 1, '2019-08-09 12:11:22', 7, NULL),
(10, 1, '2019-08-09 12:15:22', 8, NULL),
(11, 3, '2019-08-14 10:07:49', 7, NULL),
(12, 2, '2019-08-14 10:10:45', 8, NULL),
(13, 2, '2019-08-26 17:16:02', 6, NULL),
(14, 3, '2019-08-26 17:16:02', 6, NULL);
CREATE TABLE `projects` (
`project_id` int(11) NOT NULL,
`name` varchar(150) NOT NULL,
`start_date` datetime NOT NULL,
`investment_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `projects` (`project_id`, `name`, `start_date`, `investment_id`) VALUES
(1, 'site A', '2019-02-01 00:00:00', 1),
(2, 'site B', '2019-03-12 00:00:00', 2),
(3, 'Site C', '2019-04-04 00:00:00', 3),
(4, 'Site D', '2019-05-03 00:00:00', 4),
(5, 'site E', '2019-06-01 00:00:00', 5),
(6, 'site F', '2019-08-02 00:00:00', 6),
(7, 'Site J', '2019-08-01 00:00:00', 7),
(8, 'Site H', '2019-08-05 00:00:00', 8);
以下是 2019 年 8 月的结果
+--------------+-------------------+---------------+---------------+
| category_name| pre_implemntation | imp_operation | pre_operation |
+------+-------+------------+-------------++-------------++--------+
| agriculture | 1 | - | 1 |
| manufactures | 1 | - | - |
| Technology | - | 1 | - |
| services | - | 1 | - |
+--------------+-------------------+---------------+---------------+
SELECT q.year
, q.month
, q.name
, COUNT(CASE WHEN q.last_status = 2 THEN 1 END) as pre_implementation
, COUNT(CASE WHEN q.last_status = 3
AND q.previous_status = 2 THEN 1 END) as implementation_operation
, COUNT(CASE WHEN q.last_status = 3
AND (q.previous_status = 1 or q.previous_status IS NULL)
THEN 1 END) as pre_operation
FROM (
SELECT *, (SELECT MAX(p.status_id)
FROM project_status p
WHERE p.time < CONCAT(t.year,'/', t.month,'/1')
AND p.project_id = t.project_id
) as previous_status
FROM (
SELECT YEAR(time) as year
, MONTH(time) as month
, c.name
, ps.project_id
, MAX(status_id) as last_status
FROM project_status ps
JOIN projects p
ON ps.project_id = p. project_id
JOIN investments i
ON p.investment_id = i.investment_id
JOIN categories c
ON i.cat_id = c.cat_id
GROUP BY YEAR(time), MONTH(time), c.name, ps.project_id
) t
) q
GROUP BY q.year, q.month, q.name
输出
+--------+-------+---------------+--------------------+--------------------------+---------------+
| year | month | name | pre_implementation | implementation_operation | pre_operation |
+--------+-------+---------------+--------------------+--------------------------+---------------+
| 2019 | 2 | Technology | 0 | 0 | 0 |
| 2019 | 3 | Technology | 1 | 0 | 0 |
| 2019 | 4 | services | 0 | 0 | 0 |
| 2019 | 5 | agriculture | 0 | 0 | 0 |
+--------+-------+---------------+--------------------+--------------------------+---------------+
| 2019 | 8 | Technology | 0 | 1 | 0 |
| 2019 | 8 | agriculture | 1 | 0 | 1 |
| 2019 | 8 | services | 0 | 0 | 1 |
| 2019 | 8 | manufactures | 1 | 0 | 0 |
+--------+-------+---------------+--------------------+--------------------------+---------------+
我想按类别名称统计给定月份的项目状态updates/changes
我有一个类别(类别列表)、投资(投资者投资列表,包括来自类别的 category_id)、状态 table,其名称包含实施前、实施和运营状态。 一个项目包含项目 ID、名称、开始日期字段。 status 和 projects 都有多对多的关系,叫做 project_status table contains project_id, status_id, date_of_progress.
我想按类别名称
统计本月内拥有 update/change 个 status_id 的所有项目从实施前到实施 从实施到运营 从实施前到运营
CREATE TABLE `categories` (
`cat_id` int(11) NOT NULL,
`name` varchar(50) NOT NULL,
`description` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `categories` (`cat_id`, `name`, `description`) VALUES
(1, 'agriculture', ''),
(2, 'manufactures ', ''),
(3, 'Technology', ''),
(4, 'services', '');
CREATE TABLE `investments` (
`investment_id` int(11) NOT NULL,
`investment_name` varchar(100) NOT NULL,
`cat_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO `investments` (`investment_id`, `investment_name`, `cat_id`) VALUES
(1, 'Company A', 3),
(2, 'Company B', 4),
(3, 'Company C', 1),
(4, 'Company D', 2),
(5, 'Company E', 3),
(6, 'Company F', 4),
(7, 'Company G', 1),
(8, 'Company H', 2);
CREATE TABLE `status` (
`status_id` int(11) NOT NULL,
`status_name` varchar(30) NOT NULL,
`description` varchar(255) DEFAULT NULL,
`status_name_tg` varchar(50) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `status` (`status_id`, `status_name`, `description`, `status_name_tg`) VALUES
(1, 'Pre Implementation', 'Operational', 'Pre Implementation'),
(2, 'Implementation', NULL, 'Implementation'),
(3, 'Operational', NULL, 'Operational'),
(4, 'Inactive', NULL, 'Inactive'),
(5, 'Cancellation', NULL, 'Cancellation');
CREATE TABLE `project_status` (
`project_status_id` int(11) NOT NULL,
`status_id` int(11) NOT NULL,
`time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
`project_id` int(11) NOT NULL,
`reason_for_cancellation` varchar(255) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `project_status` (`project_status_id`, `status_id`, `time`, `project_id`, `reason_for_cancellation`) VALUES
(1, 1, '2019-02-24 21:51:50', 1, NULL),
(2, 2, '2019-03-26 21:52:57', 1, NULL),
(3, 1, '2019-04-30 21:57:57', 2, NULL),
(4, 1, '2019-05-26 22:04:08', 3, NULL),
(5, 3, '2019-08-24 22:06:36', 1, NULL),
(6, 2, '2019-08-11 22:07:05', 3, NULL),
(8, 1, '2019-08-01 00:14:41', 6, NULL),
(9, 1, '2019-08-09 12:11:22', 7, NULL),
(10, 1, '2019-08-09 12:15:22', 8, NULL),
(11, 3, '2019-08-14 10:07:49', 7, NULL),
(12, 2, '2019-08-14 10:10:45', 8, NULL),
(13, 2, '2019-08-26 17:16:02', 6, NULL),
(14, 3, '2019-08-26 17:16:02', 6, NULL);
CREATE TABLE `projects` (
`project_id` int(11) NOT NULL,
`name` varchar(150) NOT NULL,
`start_date` datetime NOT NULL,
`investment_id` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `projects` (`project_id`, `name`, `start_date`, `investment_id`) VALUES
(1, 'site A', '2019-02-01 00:00:00', 1),
(2, 'site B', '2019-03-12 00:00:00', 2),
(3, 'Site C', '2019-04-04 00:00:00', 3),
(4, 'Site D', '2019-05-03 00:00:00', 4),
(5, 'site E', '2019-06-01 00:00:00', 5),
(6, 'site F', '2019-08-02 00:00:00', 6),
(7, 'Site J', '2019-08-01 00:00:00', 7),
(8, 'Site H', '2019-08-05 00:00:00', 8);
以下是 2019 年 8 月的结果
+--------------+-------------------+---------------+---------------+
| category_name| pre_implemntation | imp_operation | pre_operation |
+------+-------+------------+-------------++-------------++--------+
| agriculture | 1 | - | 1 |
| manufactures | 1 | - | - |
| Technology | - | 1 | - |
| services | - | 1 | - |
+--------------+-------------------+---------------+---------------+
SELECT q.year
, q.month
, q.name
, COUNT(CASE WHEN q.last_status = 2 THEN 1 END) as pre_implementation
, COUNT(CASE WHEN q.last_status = 3
AND q.previous_status = 2 THEN 1 END) as implementation_operation
, COUNT(CASE WHEN q.last_status = 3
AND (q.previous_status = 1 or q.previous_status IS NULL)
THEN 1 END) as pre_operation
FROM (
SELECT *, (SELECT MAX(p.status_id)
FROM project_status p
WHERE p.time < CONCAT(t.year,'/', t.month,'/1')
AND p.project_id = t.project_id
) as previous_status
FROM (
SELECT YEAR(time) as year
, MONTH(time) as month
, c.name
, ps.project_id
, MAX(status_id) as last_status
FROM project_status ps
JOIN projects p
ON ps.project_id = p. project_id
JOIN investments i
ON p.investment_id = i.investment_id
JOIN categories c
ON i.cat_id = c.cat_id
GROUP BY YEAR(time), MONTH(time), c.name, ps.project_id
) t
) q
GROUP BY q.year, q.month, q.name
输出
+--------+-------+---------------+--------------------+--------------------------+---------------+
| year | month | name | pre_implementation | implementation_operation | pre_operation |
+--------+-------+---------------+--------------------+--------------------------+---------------+
| 2019 | 2 | Technology | 0 | 0 | 0 |
| 2019 | 3 | Technology | 1 | 0 | 0 |
| 2019 | 4 | services | 0 | 0 | 0 |
| 2019 | 5 | agriculture | 0 | 0 | 0 |
+--------+-------+---------------+--------------------+--------------------------+---------------+
| 2019 | 8 | Technology | 0 | 1 | 0 |
| 2019 | 8 | agriculture | 1 | 0 | 1 |
| 2019 | 8 | services | 0 | 0 | 1 |
| 2019 | 8 | manufactures | 1 | 0 | 0 |
+--------+-------+---------------+--------------------+--------------------------+---------------+