Nie wiadomości.przeczytane tylko w.przeczytane, bo aliasem jest w - nie wiadomości. Jeśli dodatkowo chcesz ograniczyć to zapytanie to wystarczy do WHERE dodać kolejny warunek. Jeśli chcesz sprawdzić jakie są nieprzeczytane wiadomości od usera X to dodajesz od LIKE '$user' lub w.od_kogo = $user_id (to da ten sam efekt), a jeśli chcesz sprawdzić jakich wiadomości user X nie przeczytał to walisz do LIKE '$user' lub w.do_kogo = '$user_id' (znów zamiennik).
Czyli ostatecznie masz w wariantach:
a) wiadomości nieprzeczytane wysłane przez użytkownika $user (gdy jako login) lub $user_id (gdy znamy tylko jego id)
SELECT w.id_w, u1.nazwa AS od, u2.nazwa AS do, w.tekst FROM wiadomosci w LEFT JOIN userzy u1 ON w.od_kogo = u1.u_id LEFT JOIN userzy u2 ON w.do_kogo = u2.u_id WHERE w.przeczytane = 0 AND od LIKE '.$user.' ORDER BY w.id_w DESC
SELECT w.id_w, u1.nazwa AS od, u2.nazwa AS do, w.tekst FROM wiadomosci w LEFT JOIN userzy u1 ON w.od_kogo = u1.u_id LEFT JOIN userzy u2 ON w.do_kogo = u2.u_id WHERE w.przeczytane = 0 AND w.od_kogo = '.$user_id.' ORDER BY w.id_w DESC

wiadomości nieprzeczytane przysłane dla użytkownika $user (gdy jako login) lub $user_id (gdy znamy tylko jego id)
SELECT w.id_w, u1.nazwa AS od, u2.nazwa AS do, w.tekst FROM wiadomosci w LEFT JOIN userzy u1 ON w.od_kogo = u1.u_id LEFT JOIN userzy u2 ON w.do_kogo = u2.u_id WHERE w.przeczytane = 0 AND do LIKE '.$user.' ORDER BY w.id_w DESC
SELECT w.id_w, u1.nazwa AS od, u2.nazwa AS do, w.tekst FROM wiadomosci w LEFT JOIN userzy u1 ON w.do_kogo = u1.u_id LEFT JOIN userzy u2 ON w.do_kogo = u2.u_id WHERE w.przeczytane = 0 AND w.do_kogo = '.$user_id.' ORDER BY w.id_w DESC
Oczywiście $user i $user_id są zmiennymi php, które musisz wpleść w składnię zapytania. Od, do, w.od_kogo, w.do_kogo i w.przeczytana można mieszać w WHERE tworząc odpowiednie układy. Zauważ, że używając od i do, musisz użyć pojedynczych apostrofów i LIKE, gdyż mamy do czynienia ze zmienną tekstową. Dawno nie robiłem porównań dla tekstówek więc od = '$user' może zadziałać (choć nie sądzę), ale musiałbyś sprawdzić. Na pewno przeszukiwanie po id będzie szybsze bo masz tam ustawione indeksy, więc drugie warianty powinny działać szybciej. LIKE jest wolniejszy, a tutaj dodatkowo kolumna na której działa (login) nie ma indeksu.
Co do pytania ostatniego to chyba już się wyjaśniło z kodem powyżej. W warunku dajesz
WHERE do LIKE 'admin'
Nie mam ochoty wywoływać flame'a. Tym bardziej, że nie znamy wielkości tabel zarówno wiadomości jak i userów oraz typu bazy, a chyba zauważyłeś, że podane zostały wybiórczo kolumny i całość jest bardziej rozbudowana. To także ma wpływ na szybkość skryptów naszych. To, że w zależności czy jest to Firebird, Oracle, Mysql, MSSQL czy Postgress czasy mogą być różne, jest dla mnie równie oczywiste. Zarówno jednak newsów jak i userów z każdym dniem przybywa. Nowa baza jest szybka, ale niech się zacznie zapełniać i stronę zacznie odwiedzać coraz więcej userów to wtedy takie drobiazgi mają wpływ i bez optymalizacji oraz cache'owania wyników najczęstszych zapytań daleko nie pociągnie się. Albo raczej zajedzie bazę ilością nadmiarowych operacji. Wiem, że wspomniana przez Ciebie jest szybsza w działaniu niż MySQL, ale też nie wszędzie jest ona dostępna. Dla faktycznych testów należałoby oba zapytania puścić w tych samych warunkach dla różnych stopni zapełnienia bazy danymi i dla różnych rodzajów baz. Ja pracuję w firmie, gdzie mam pod sobą kilka serwisów mających dziennie kilkadziesiąt tysięcy odsłon i około 2k real users według google analytics, czyli tych co
nie blokują ich skryptów. Optymalizacja na takich ma znaczenie i dlatego staram się mieć jak najbardziej optymalne rozwiązania. Jeśli pracujesz na takich lub większych serwisach to zapewne mnie rozumiesz. Nie zaczynajmy więc niepotrzebnie flame'a i nie zaśmiecajmy niepotrzebną wojną tematu.
Moglibyśmy przecież się spierać czy gdy wiadomości jest X, userów w bazie Y, a odwiedzających jednocześnie Z to od pewnego momentu któreś z naszych rozwiązań może być szybsze o ileś od drugiego. Ja staram nie odrywać jednego zapytania od kontekstu działania całości serwera bo jest różnica w serwerze na localhoście i publicznym, do którego ma dostęp więcej niż jedna osoba i także masz tego świadomość podobnie jak ja. Dopiero po postawieniu serwisu w necie wychodzi jego optymalizacja, gdy do bazy jest jednocześnie wiele zapytań. Tutaj już różnica kilkudziesięciu czy kilkuset milisekund przy często wywoływanych funkcjach zaczyna grać rolę. Ale to już bardziej do tematu lub działu o optymalizacji powinno by było zostać przeniesione. Nie uważasz? Za dużo czynników ma wpływ ale przy jednakowym obciążeniu początkowa niewielka różnica zaczyna się powiększać. I stąd każdy niepotrzebny JOIN, każdy niepotrzebny SELECT to dodatkowy narzut czasowy, którego można uniknąć przebudowując zapytanie. I tylko o to mi chodzi. Nie ma co kruszyć kopii gdy nie jest to potrzebne. Ja testy swoich zapytań i skryptów mam codziennie idąc do pracy. Mam to szczęście, że pracuję w zawodzie wyuczonym i mam z tym kontakt przynajmniej 8 godzin dziennie jako praca, a i nieraz jeszcze po niej - hobbystycznie.