У меня есть три таблицы для отслеживания писем и их назначенных категорий: Email
хранит содержимое письма, Category
перечисляет категории и Classification
связывает Email
идентификатор записи с Category
идентификатором записи. Схема с примерами данных и запросом доступна в SQLFiddle: http://sqlfiddle.com/#!9/a410a6/26/0
CREATE TABLE `Category` (
`id` int(6) unsigned NOT NULL,
`name` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE `Mail` (
`id` int(6) unsigned NOT NULL,
`content` varchar(500) NOT NULL,
`date` datetime NOT NULL,
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
CREATE TABLE `Classification` (
`id` int(6) unsigned NOT NULL,
`mail_id` int(6) unsigned NOT NULL,
`category_id` int(6) unsigned NOT NULL,
FOREIGN KEY (mail_id) REFERENCES Mail(id),
FOREIGN KEY (category_id) REFERENCES Category(id),
PRIMARY KEY (`id`)
) DEFAULT CHARSET=utf8;
INSERT INTO `Category` (`id`, `name`) VALUES
('1', 'Important'),
('2', 'Urgent'),
('3', 'Normal');
INSERT INTO `Mail` (`id`, `content`, `date`) VALUES
('1', 'Important Email', '2019-01-04T13:53:52'),
('2', 'Urgent Email', '2019-01-19T13:53:52'),
('3', 'Very Urgent Email', '2019-01-24T13:53:52'),
('4', 'Quite Urgent Email', '2019-01-24T13:53:52'),
('5', 'Normal Email', '2019-01-21T13:53:52'),
('6', 'Regular Email', '2019-01-14T13:53:52'),
('7', 'Regular Email', '2019-01-23T13:53:52'),
('8', 'Regular Email', '2019-01-23T13:53:52'),
('9', 'Regular Email', '2019-01-20T13:53:52'),
('10', 'Very Urgent Email', '2019-01-25T13:53:52'),
('11', 'Very Urgent Email', '2019-01-25T13:53:52');
INSERT INTO `Classification` (`id`, `mail_id`, `category_id`) VALUES
('1', '1', '1'),
('2', '2', '2'),
('3', '3', '2'),
('4', '4', '2'),
('5', '5', '3'),
('6', '6', '3'),
('7', '6', '3'),
('8', '6', '3'),
('9', '6', '3'),
('10', '6', '2'),
('11', '6', '2');
Я хочу вернуть количество писем, полученных по каждой категории для каждой записанной даты, т.е. мои ожидаемые результаты будут
+----------------------+-----------+----------+
| date | name | count(*) |
+----------------------+-----------+----------+
| 2019-01-04T13:53:52Z | Important | 1 |
| 2019-01-14T13:53:52Z | Normal | 1 |
| 2019-01-19T13:53:52Z | Urgent | 1 |
| 2019-01-20T13:53:52Z | Normal | 1 |
| 2019-01-21T13:53:52Z | Normal | 1 |
| 2019-01-23T13:53:52Z | Normal | 2 |
| 2019-01-24T13:53:52Z | Urgent | 1 |
| 2019-01-25T13:53:52Z | Urgent | 2 |
+----------------------+-----------+----------+
Для этого я запускаю следующий запрос с двойной групповой фильтрацией, фильтруя таблицу Classification
:
SELECT Mail.date, Category.name, count(*) FROM Mail, Classification, Category WHERE Category.id = Classification.category_id AND Classification.mail_id = Mail.id GROUP BY Mail.date, Category.name
Что дает мне следующие результаты:
+----------------------+-----------+----------+
| date | name | count(*) |
+----------------------+-----------+----------+
| 2019-01-04T13:53:52Z | Important | 1 |
| 2019-01-14T13:53:52Z | Normal | 4 |
| 2019-01-14T13:53:52Z | Urgent | 2 |
| 2019-01-19T13:53:52Z | Urgent | 1 |
| 2019-01-21T13:53:52Z | Normal | 1 |
| 2019-01-24T13:53:52Z | Urgent | 2 |
+----------------------+-----------+----------+
Что совершенно неправильно.
Я пытался подставить оператор WHERE
для JOIN
:
SELECT Mail.date, Category.name, count(*) FROM (Mail, Category) RIGHT JOIN Classification ON Category.id = Classification.category_id AND Classification.mail_id = Mail.id GROUP BY Mail.date, Category.name `
Но я получаю те же результаты, что и выше.
Почему эти запросы возвращают эти ошибочные результаты и что я должен сделать, чтобы их исправить?