LEFT - JOIN и WHERE не работает должным образом в запросе - PullRequest
0 голосов
/ 12 мая 2019

У меня есть 3 таблицы: residual_types, контейнеры, collection и collection_container.Каждый контейнер имеет тип residual_type, и между контейнерами и коллекциями существует отношение «многие ко многим».

Мне нужно сделать запрос, который в определенный день сообщает мне, сколько массы было собрано для каждого residual_type, дажехотя нет никаких записей, связанных с residual_type.Например, в данный день «ORGANIC» residual_types имеет собранные 850 кг, он показывает «ORGANIC | 850», но если бы он имел 0 кг, он отображал бы «ORGANIC | 0».

Thisявляется запросом, который я использую, но кажется, что он не соответствует предложению WHERE для collection.creation_time и возвращает все записилюбые записи.

SELECT residual_types.name AS name, IFNULL(SUM(collection_container.mass),0) AS mass
FROM residual_types
INNER JOIN containers ON containers.residual_type_id = residual_types.id
INNER JOIN collection_container ON collection_container.container_id = containers.id
INNER JOIN collections ON collection_container.collection_id = collections.id
WHERE collections.creation_time BETWEEN 1557637200 AND 1557723599
GROUP BY residual_types.id
ORDER BY mass DESC

Если нет никаких коллекций, связанных с residual_type, тогда набор результатов должен выглядеть следующим образом:

+---------+------+
| name    | mass |
+---------+------+
| organic | 0    |
+---------+------+
| paper   | 0    |
+---------+------+
| plastic | 0    |
+---------+------+

Ответы [ 2 ]

1 голос
/ 12 мая 2019

Ваша проблема в том, что суммируемое вами значение всегда будет числом, независимо от того, была коллекция или нет. Вы должны указать сумму с тем, была ли коллекция, или нет, что вы можете сделать, изменив это выражение с

IFNULL(SUM(collection_container.mass), 0)

до

SUM(CASE WHEN collections.id IS NOT NULL THEN collection_container.mass ELSE 0 END)
0 голосов
/ 12 мая 2019

Я думаю, что проблема в дизайне в том, что масса содержится в collection_container.Я бы ожидал этого в коллекциях.Эффект состоит в том, что масса найдена до левого соединения (которое не выполняется в дату).

Например

drop table if exists residual_types,containers,collection_container,collections;
create table residual_types(id int,name varchar(3));
create table containers(id int,residual_type_id int);
create table collection_container(container_id int,collection_id int,mass int);
create table collections(id int,creation_time bigint);

insert into residual_types values(1,'aaa'),(2,'bbb'),(3,'ccc');
insert into containers values(1,1),(2,1),(3,1),(4,1);
insert into collection_container values(1,10,100),(1,20,100),(1,30,100);
insert into collections values(10,1557637100),(20,1557637200),(30,1557723599);



SELECT residual_types.name AS name, collections.creation_time, 
         IFNULL(SUM(collection_container.mass),0) AS mass
FROM residual_types
INNER JOIN containers ON containers.residual_type_id = residual_types.id
INNER JOIN collection_container ON collection_container.container_id = containers.id
LEFT JOIN collections ON collection_container.collection_id = collections.id AND collections.creation_time BETWEEN 1557637200 AND 1557723599
GROUP BY residual_types.id,collections.creation_time
ORDER BY mass DESC;

+------+---------------+------+
| name | creation_time | mass |
+------+---------------+------+
| aaa  |          NULL |  100 |
| aaa  |    1557637200 |  100 |
| aaa  |    1557723599 |  100 |
+------+---------------+------+
3 rows in set (0.00 sec)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...