I’m wondering why does the following queries give me a slightly different dataset:
SELECT t.name, COUNT(e.id) FROM event_type t LEFT JOIN event e ON t.id = e.type_id AND e.start BETWEEN ? AND ? GROUP BY t.name; SELECT t.name, COUNT(e.id) FROM event_type t LEFT JOIN event e ON t.id = e.type_id WHERE e.start BETWEEN ? AND ? GROUP BY t.name;
So I just moved BETWEEN clause to the main body, logically, it does not matter where to apply it, but the result says it matters. Any suggestions? Thanks!
UPD: tried on MySQL 5.6
create table event_type
(
id int auto_increment primary key,
name varchar(100) not null,
constraint UNIQ_93151B825E237E06 unique (name)
) collate = utf8_unicode_ci;
create table event
(
id int auto_increment primary key,
type_id int null,
start datetime not null,
...
constraint FK_3BAE0AA7C54C8C93
foreign key (type_id) references event_type (id)
) collate = utf8_unicode_ci;
create index IDX_3BAE0AA7C54C8C93
on event (type_id);
Advertisement
Answer
Maybe it’s hard to answer this question without some images! but I try.
Let’s assume this is the event_type table
| Id | Name |
|---|---|
| 1 | First |
| 2 | Second |
Events table:
| Id | TypeId | Start |
|---|---|---|
| 5 | 1 | 2022-10-01 |
| 6 | 1 | 2022-10-10 |
So for this query:
SELECT t.name, COUNT(e.id) FROM event_type t LEFT JOIN event e ON t.id = e.type_id AND e.start BETWEEN '2022-10-01' AND '2022-10-05' GROUP BY t.name;
The result will be:
| Name | Count(e.id) |
|---|---|
| First | 1 |
| Second | 0 |
But why? becuase sql engine when try to get result on left join, it will check both of id and start, actually the result of prevois query is like this:
| Id | Name | Id | TypeId | Start |
|---|---|---|---|---|
| 1 | First | 5 | 1 | 2022-10-01 |
| 2 | Second | null | null | null |
That’s it! When you try to use Between in where clause, in fact you are filtering the null values so sql would ingore them and the final result would be different.
I hope it’s clear enough!