Pytanie dotyczy następującego przykładu:
show tables like "test_%";
drop table if exists test_task;
create table test_task ( id int auto_increment primary key, Code tinytext );
drop table if exists test_receiver;
create table test_receiver ( taskid int, receiverid int, primary key (taskid,receiverid) );
drop table if exists test_supplier;
create table test_supplier ( taskid int, supplierid int, primary key (taskid,supplierid) );
insert test_task (code) values ('Aaa'),('Bbb'),('Ccc'),('Ddd'),('Eee'),('Fff'),('Ggg'),('Hhh'),('Iii'),('Jjj'),('Kkk'),('Lll'),('Mmm'),('Nnn'),('Ooo'),('Ppp'),('Qqq'),('Rrr'),('Sss'),('Ttt'),('Uuu'),('Vvv'),('Www'),('Xxx'),('Yyy'),('Zzz');
insert test_receiver (taskid,receiverid) values (13,1),(13,2),(13,3),(13,5),(13,7),(13,11),(8,2),(8,4),(8,6);
insert test_supplier (taskid,supplierid) values (13,17),(13,19),(13,23),(12,24),(12,25),(12,26);
select
T.id Id,
T.Code Kod,
count(S.supplierid) IloscDost,
count(R.receiverid) IloscOdb
from
test_task T
left join
test_supplier S on S.taskid=T.id
left join
test_receiver R on R.taskid=T.id
group by
T.Id
having
IloscDost>0 or IloscOdb>0
;
select
T.id Id,
T.Code Kod,
count(distinct S.taskid,S.supplierid) IloscDost,
count(distinct R.taskid,R.receiverid) IloscOdb
from
test_task T
left join
test_supplier S on S.taskid=T.id
left join
test_receiver R on R.taskid=T.id
group by
T.Id
having
IloscDost>0 or IloscOdb>0
;
Pierwsze zapytanie ma dwie wady, po pierwsze zwraca niepoprawne odpowiedzi kiedy (IloscDost>1 oraz IloscOdb>1) po drugie działa na pewno baaaardzo długo ponieważ jeżeli IloscDost=1000 oraz IloscOdb=1000 to już będzie przeanalizowano milion rekordów !
Drugie zapytanie działa poprawnie, pytanie czy została druga wada - długie działanie ?
I następne pytanie, czy da się to zrobić bez left join?