Левое присоединение не возвращает все записи из левой таблицы - PullRequest
0 голосов
/ 04 августа 2020

Я хочу получить счет, выполнив join с двумя таблицами, я делаю group by и left join.

Но я не получаю всю строку, если эта запись не сопоставить другую таблицу.

Здесь, в данном запросе:

create table UserTable (
  Id integer not null,
  Name varchar(12) not null
);

insert into UserTable  values (1,  'A B');
insert into UserTable  values (2,  'A C');
insert into UserTable  values (3,  'A C A C');
insert into UserTable  values (4,  'A C C');
insert into UserTable  values (5,  'A C B');
insert into UserTable  values (6,  'A C C');
insert into UserTable  values (7,  'A C D');
insert into UserTable  values (8,  'A C E');
insert into UserTable  values (9,  'A C F');


create table LogTable (
  LogId integer not null,
  Username varchar(12) not null,
  Event varchar(12) not null
);

insert into LogTable  values (1, 'A C A C', 'Read');
insert into LogTable  values (2, 'A C F', 'Write');
insert into LogTable  values (3, 'A C F', 'Read');
insert into LogTable  values (4, 'A C C', 'Update');
insert into LogTable  values (5,'A C C', 'Read');
insert into LogTable  values (6,'A C F', 'Read');
insert into LogTable  values (7,'A C F', 'Update');
insert into LogTable  values (7,'A C F', 'Write');
insert into LogTable  values (7,'A C E','Update');
insert into LogTable  values (7,'A C F', 'Delete');
insert into LogTable  values (10,'A C B', 'Delete');
insert into LogTable  values (11, 'A C F','Copy');
insert into LogTable  values (12, 'A C B','Read');
insert into LogTable  values (13, 'A C F','Update');
insert into LogTable  values (14, 'A C F','Copy');
insert into LogTable  values (15, 'A C F','Read');
insert into LogTable  values (16, 'A C F','Update');
insert into LogTable  values (17, 'A C F','Copy');
insert into LogTable  values (18, 'A C C','Read');
insert into LogTable  values (19, 'A C D','Update');

Я делаю:

SELECT COUNT(*) as Read,UT.Name, UT.Id 
FROM UserTable UT 
LEFT JOIN LogTable LT ON LT.Username = UT.Name 
WHERE LT.Event = 'Read'
GROUP by UT.Name, UT.Id

Я хочу получить все записи из UserTable, также, если он не существует в LogTable

Если не существует, сделайте ReadCount как 0.

Почему Left Joining не возвращает все записи из UserTable в этом запросе?

Желаемый результат:

Id  |   Name    |   ReadCount
-----------------------------
1   |   A B     |   0
2   |   A C     |   0
3   |   A C A C |   1
4   |   A C C   |   2
5   |   A C B   |   1
6   |   A C C   |   2
7   |   A C D   |   0
8   |   A C E   |   0
9   |   A C F   |   3

Ответы [ 2 ]

2 голосов
/ 04 августа 2020

Вам нужно переместить условие в предложение ON. Однако вам не нужно COUNT(*), потому что вы хотите подсчитать количество совпадений. Это будет:

SELECT UT.Name, UT.Id , COUNT(LT.UserName) as num_read
FROM UserTable UT LEFT JOIN
     LogTable LT
     ON LT.Username = UT.Name AND LT.Event = 'Read'
GROUP by UT.Name, UT.Id;

Тем не менее, этот тип запроса часто быстрее с коррелированным подзапросом:

select ut.*,
       (select count(*)
        from logtable lt
        where lt.username = ut.name and lt.event = 'Read'
       ) as num_read
from usertable ut;

В частности, это может использовать индекс на logtable(username, event).

1 голос
/ 04 августа 2020
SELECT COUNT(*) as Read,UT.Name, UT.Id 
FROM UserTable UT 
LEFT JOIN LogTable LT ON LT.Username = UT.Name 
WHERE LT.Event = 'Read'
GROUP by UT.Name, UT.Id

вы использовали WHERE LT.Event = 'Read', что делает его внутренним соединением, поэтому вы не получаете все строки левой таблицы

SELECT COUNT(*) as Read,UT.Name, UT.Id 
FROM UserTable UT 
LEFT JOIN LogTable LT ON LT.Username = UT.Name 
 and  LT.Event = 'Read'

GROUP by UT.Name, UT.Id

переместите условие в предложение on

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...