Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: 5 LEFT JOIN-ów?
Forum PHP.pl > Forum > Bazy danych > MySQL
piotrek24
Mam tabelę "uzytkownicy" z polami:

uzytkownik_id
uzytkownik_nazwa

oraz tabelę "zadania" z polami

zadanie_id
czynnosc_1
uzytkownik_id_1
czynnosc_2
uzytkownik_id_2
czynnosc_3
uzytkownik_id_3
czynnosc_4
uzytkownik_id_4
czynnosc_5
uzytkownik_id_5

Oczywiście poszczególne czynności mogą wykonywać ci sami bądź różni użytkownicy.

I teraz chcę wyświetlić 1 wiersz z tabeli "zadania" przydzielając każdemu numerowi id użytkownika odpowiednią mu nazwę z tabeli "uzytkownicy". Czy jedynym i najprostszym rozwiązaniem tego problemu jest użycie aż (a może tylko?) 5 złączeń zewnętrznych LEFT JOIN ?

Czyli:

  1. SELECT a.czynnosc_1, a.czynnosc_2, a.czynnosc_3, a.czynnosc_4, a.czynnosc_5, b.uzytkownik_nazwa AS uzytkownik_nazwa_1,
  2. c.uzytkownik_nazwa AS uzytkownik_nazwa_2, d.uzytkownik_nazwa AS uzytkownik_nazwa_3, e.uzytkownik_nazwa
  3. AS uzytkownik_nazwa_4, f.uzytkownik_nazwa AS uzytkownik_nazwa_5
  4. FROM zadania a
  5. LEFT JOIN uzytkownicy b ON a.uzytkownik_id_1 = b.uzytkownik_id
  6. LEFT JOIN uzytkownicy c ON a.uzytkownik_id_2 = c.uzytkownik_id
  7. LEFT JOIN uzytkownicy d ON a.uzytkownik_id_3 = d.uzytkownik_id
  8. LEFT JOIN uzytkownicy e ON a.uzytkownik_id_4 = e.uzytkownik_id
  9. LEFT JOIN uzytkownicy f ON a.uzytkownik_id_5 = f.uzytkownik_id
  10. WHERE zadanie_id = 1
AxZx
a jak bedzie 100 uzytkownikow to co zrobisz?
chyba jest zle baza zaprojektowana.
a moze to specjalnie tak?
piotrek24
Nie, nie będzie 100 użytkowników :-), w jednym wierszu tabeli "zadania" jest zawsze dokładnie 5 użytkowników. Chodzi o to że każde zadanie ma dokładnie 5 etapów, a każdy etap może wykonać inny użytkownik. I zamiast do tabeli "zadania" dodawać pełne nazwy użytkowników dodaje tylko ich numery id i potem pobierając rekord z tabeli "zadania" chcę tym numerom ID użytkowników przyporządkować ich odpowiednie nazwy z tabeli "uzytkownicy".

To zapytanie co jest powyżej jak najbardziej działa i w zasadzie może tak zostać jednak moje pytanie dotyczy tego czy to jest jedyne rozwiązanie? i czy nie da sie tego zrobić np. prościej?.
cojack
Ehm i na kiego tam left joiny?

Nie testowane bo nie mam gdzie ale patrz:

  1. SELECT * FROM uzytkownicy, zadania WHERE uzytkownik_id_1 = (uzytkownik_id = 1) AND uzytkownik_id_2 = (uzytkownik_id = 2) AND uzytkownik_id_3 = (uzytkownik_id = 3) AND uzytkownik_id_4 = (uzytkownik_id = 4) AND zadanie_id = 1


Jak można było taką tabelę zrobić... toż już przecież lepiej jest zrobić tak:

1 tabela: uzytkownicy
uzytkownik_id | uzytkownik_name

2 tabela: zadania
zadanie_id | użytkownik_id | czynnosc_id

3 tabela: czynnosci
czynnosc_id | czynnosc_name

I wtedy robisz tak:
  1. SELECT * FROM uzytkownicy, zadania, czynnosci WHERE uzytkownik_id.uzytkownicy = uzytkownik_id.zadania AND czynnosc_id.zadania = czynnosc_id.czynnosci AND zadanie_id = 1


i wyswietli Ci wszystkich uzytkownikow o wskazanym id zadania i ich nazwy oraz nazwy czynnosci wykonywanych przy danym id zadania.

Po co sobie życie komplikować?
piotrek24
Pomińmy zmiany w strukturze tabeli, ona taka ma być jak jest i już smile.gif. Nie będę wyjaśniał dlaczego.

Co do propozycji zapytania to nie za bardzo go rozumiem...
Nie wiem co ma oznaczać zapis: "... uzytkownik_id_1 = (uzytkownik_id = 1)... "

Poza tym skąd ja mam wiedzieć że tam będzie użytkownik o id = 1, 2, 3, 4 i 5 ?, może to być użytkownik o id = 114, id = 568 itd.
Choć nawet jak są tam użytkownicy o numerach 1,2,3,4 i 5 to zapytanie nie działa. Nie powoduje błędu ale i nie zwraca żadnego wyniku
cojack
  1. SELECT * FROM uzytkownicy, zadania WHERE zadania.uzytkownik_id_1 = (uzytkownicy.uzytkownik_id = 1) AND zadania.uzytkownik_id_2 = (uzytkownicy.uzytkownik_id = 2) AND zadania.uzytkownik_id_3 = (uzytkownicy.uzytkownik_id = 3) AND zadania.uzytkownik_id_4 = (uzytkownicy.uzytkownik_id = 4) AND zadanie_id = 1


@EDIT \/

dobra daje sobie spokój...
piotrek24
Cytat(cojack @ 4.06.2008, 18:07:50 ) *
zadania.uzytkownik_id_1 = (uzytkownicy.uzytkownik_id = 1)


Taki zapis nie działa i nie wiem w ogóle co chcesz tym uzyskać?
Jak ja tym Twoim zapytaniem mam "odebrać" 5 różnych nazwisk z tabeli użytkownicy?

W wyniku zapytania chcę uzyskać coś takiego:

zadanie_id
czynnosc_1
uzytkownik_nazwa
czynnosc_2
uzytkownik_nazwa
czynnosc_3
uzytkownik_nazwa
czynnosc_4
uzytkownik_nazwa
czynnosc_5
uzytkownik_nazwa

Nie wiem czy dobrze przemyślałeś to co piszesz... albo ja czegoś tutaj kompletnie nie rozumiem.
Sedziwoj
@piotrek24
Jak masz źle zrobioną bazę to się potem nie dziw, że wychodzą jakieś głupoty próbując z niej coś pobrać.
piotrek24
Cytat(Sedziwoj @ 5.06.2008, 16:04:14 ) *
@piotrek24
Jak masz źle zrobioną bazę to się potem nie dziw, że wychodzą jakieś głupoty próbując z niej coś pobrać.


Ja tu nikogo nie proszę o ocenę mojej bazy danych. Żadne głupoty mi nie wychodzą i wszystko działa jak należy, ale specem nie jestem i chciałem się poradzić kogoś bardziej doświadczonego czy można by to zapytanie uprościć (choć od początku wydaje mi się że nie).

Tabele napisałem w uproszczeniu, w rzeczywistości wygląda inaczej. Poszczególne czynności nie składają się tylko z jednego pola tylko z kilku a ich liczba zmienia się w zależności od rodzaju czynności, dlatego pomysł cojack-a nie wchodzi w grę. Ale powtarzam, mój problem nie dotyczy budowy tabeli tylko zapytania więc napisałem to w uproszczeniu dla łatwego zrozumienia.
Sedziwoj
piotrek24 ty nadal nie rozumiesz o co mi chodzi.
Do tego nie zakładaj nigdy, że obecne rozwiązanie jest najlepsze, a to robisz co do bazy, na pewno nie podamy lepszego rozwiązania jeśli nie znamy specyfiki problemu.
W tym wypadku można było coś zrobić, ale straciło by się pewne informacje, więc na pewno takie rozwiązanie odpadnie. A to przez to, że baza jest źle napisana.

Tak więc zostaje taki dziwoląg, który musi pięć razy złączać.
nospor
tyle postow o nic winksmiley.jpg a pytanie bylo takie proste:
Cytat
To zapytanie co jest powyżej jak najbardziej działa i w zasadzie może tak zostać jednak moje pytanie dotyczy tego czy to jest jedyne rozwiązanie? i czy nie da sie tego zrobić np. prościej?.

Odpowiedź: nie, nie da się tego zrobić prościej. Użycie tu 5 left joinow tak jak ty to zrobiles to jedyne sensowne rozwiązanie smile.gif

edit: choć przepraszam, można by się tu pokusić o widoki
piotrek24
Cytat(nospor @ 6.06.2008, 09:30:29 ) *
Odpowiedź: nie, nie da się tego zrobić prościej. Użycie tu 5 left joinow tak jak ty to zrobiles to jedyne sensowne rozwiązanie smile.gif


Dzięki, taka odpowiedź mi wystarczy. A o widokach poczytam.
Sedziwoj
Cytat(nospor @ 6.06.2008, 09:30:29 ) *
tyle postow o nic winksmiley.jpg a pytanie bylo takie proste:

Odpowiedź: nie, nie da się tego zrobić prościej. Użycie tu 5 left joinow tak jak ty to zrobiles to jedyne sensowne rozwiązanie smile.gif

edit: choć przepraszam, można by się tu pokusić o widoki


Chyba trochę za daleko z tą prostotą zaszedłeś, nigdzie nie było na początku napisane o tym że nie można zmieniać struktury bazy, a jakby ją zmienić na pewno dało by się to prościej zrobić.
A wiedzę że też z czytaniem moich postów jest problem, bo nie wprost napisałem, że lepiej się tego nie da zrobić.

A co do widoków (tu dzież zwanych perspektywami, z angielskiego VIEW), to tylko ukryją tą kwerendę, ułatwią jej używanie, ale nie ułatwią bazie pracy.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.