Musíte vložit kontrolu uživatele do spojení, ne do podmínky where, jako je:
SELECT c.course_id,l.topic,l.id,l.vid_duration,p.*
FROM courses c
LEFT JOIN lessons l ON l.course_id=c.course_id
LEFT JOIN progress p ON l.id = p.lesson_id and p.user_id = :userid
WHERE c.slug = :course
Důvodem je to, že JOINS používají "levý spoj" (což je implicitně vnější spojení". Tento typ spojení znamená, že pokud podmínka funguje, vrátí všechna data sloupců pro danou tabulku pro daný řádek. podmínka nefunguje, vrátí všechna data pro tabulky uvedené dříve, ale pro tabulku uvedenou v řádku vrátí NULLS pro všechny tyto sloupce.
Omlouvám se za tento popis, protože je těžké vyjádřit slovy, jak přesně funguje složité vnější (nebo levé) spojení, aniž by se to nějak rozklepalo.