Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [SQL] Optymalizacja zapytania
Forum PHP.pl > Forum > Przedszkole
sadistic_son
Witam,

Mam 5 tabel:


Stworzyłem zapytanie:
  1. SELECT t_book.id_book, t_book.title, t_book.second_title, t_book.publisher, t_book.date_published, t_book.isbn, t_book.pages, t_book.format, t_book.for_adult, t_book.price, t_book.review, t_book.picture, t_book_author.id_book_author, t_book_author.f_book, t_book_author.f_author, t_author.id_author, t_author.name, t_author.second_name, t_author.surname, t_author.nationality, t_author.opinion, t_author.id_author, t_author.name, t_author.second_name, t_author.surname, t_author.nationality, t_author.opinion, t_title.id_title, t_title.title, t_author_title.id_author_title, t_author_title.f_author, t_author_title.f_title
  2. FROM t_book, t_book_author, t_author, t_author_title, t_title
  3. WHERE t_author_title.f_author = t_author.id_author
  4. AND t_author_title.f_title = t_title.id_title
  5. AND t_book_author.f_book = t_book.id_book
  6. AND t_book_author.f_author = t_author.id_author

Ale jest ono niekompletne bo wyniki wyglądają następująco:
Kod
1 | tytul1 | tytul2 | wydawn1 | 2009 | isbn1 | 412 | 2x5 | 0 | 12 | fajna dosc | c:/ | 1 | 1 | 1 | 1 | zenon1 | zbigniew2 | kowal | polak | znany jest | 1 | zenon1 | zbigniew2 | kowal | polak | znany jest | 2 | mgr | 1 | 1 | 2 |

1 | tytul1 | tytul2 | wydawn1 | 2009 | isbn1 | 412 | 2x5 | 0 | 12 | fajna dosc | c:/ | 1 | 1 | 1 | 1 | zenon1 | zbigniew2 | kowal | polak | znany jest | 1 | zenon1 | zbigniew2 | kowal | polak | znany jest | 1 | inz | 2 | 1 | 1 |

1 | tytul1 | tytul2 | wydawn1 | 2009 | isbn1 | 412 | 2x5 | 0 | 12 | fajna dosc | c:/ | 2 | 1 | 2 | 2 | janek1 | alek2 | sypniewski | polak | znany jest tez | 2 | janek1 | alek2 | sypniewski | polak | znany jest tez | 3 | dr | 4 | 2 | 3 |

2 | tytul2 | tytul3 | wydaw22n1 | 2109 | isbn133 | 4120 | 2x52 | 1 | 122 | f11ajna dosc | c:dwukropek | 3 | 2 | 3 | 3 | janek222 | alek3333 | sypn4444 | pola555k | znan555555y jest tez | 3 | janek222 | alek3333 | sypn4444 | pola555k | znan555555y jest tez | 0 | brak | 6 | 3 | 0 |


Czyli książka pierwsza ma 2 autorów z których jeden ma 1 tytuł a drugi ma 2 tytuły. Przez co książka o id=1 jest powtórzona 3 razy.
Jak powinno wyglądać zapytanie aby w wyniku książka pojawiała się tylko raz a jedynie autorzy z przydzielonymi do nich tytułami byli wyświetlani tyle razy ilu ich jest?
thek
Myślę, że niepotrzebnie tak rozwarstwiłeś tytuły. Patrząc na stopnie nie ma ich wiele i wydzielanie magistra od inżyniera jako osobny tytuł jest niezbyt sensowne. Tak naprawdę możliwych kombinacji jest mało, bo tytuły naukowe się wielokrotnie wykluczają. Technik jest zastępowany przez inżyniera (który w Polsce jest najwyższym możliwym stopniem technicznym), doktor "nadpisuje" magistra, i tak dalej. Kombinacje więc dają niewiele więcej niż 10 kombinacji smile.gif Niektóre zaś są "abstrakcją" i nie spotkasz choćby połączeń doktora oraz technika smile.gif Oczywiście zawsze możesz używać łączeń i grupując kombinować z GROUP_CONCAT, tyle, że moim zdaniem lepiej to robić dopiero na poziomie autorów, nie zaś już przy tytułach naukowych.
Cysiaczek
Propozycja normalnego tytułu na PW do dowolnego moderatora spowoduje, że temat zostanie otwarty.
Zamykam

Ok, załatwione
sadistic_son
No tak ale jesli w tabeli t_author umieszczę pole 'title' to w twakim wypadku autor będzie mógł mieć co najwyżej jeden tytuł naukowy. To tyklucza już możliwość chociażby mgr inż.
Z kolei wpisanie tego 'mgr inż' do jednego pola uniemożliwi wyszukiwanie po tytule naukowym. Np. 'wyświetl książki napisane przez profesorów, magistrów czy mgr inż.

Ale nawet pomijając kwestię tytułów nadal pozostaje ten problem, że książka id=1 pojawi się 2 razy bo napisało ją 2 autorów.

EDIT:
Metodą 'super-chłopo-logiczną' udało mi się osiągnąć zamierzony efekt:
Kod
tytul:potop Drugi tytul: szwedzki Autorzy: mgr inz zenon1,kowal
dr janek1,sypniewski


tytul: kosmiczna wyprawa Drugi tytul: cos tam w prozni Autorzy: prof janek222,sypn4444


Realizuje to kod składający się z 3 zapytań, 3 pętli while itp.
  1. $query="SELECT id_book , title , second_title FROM t_book";
  2. $result=mysql_query($query);
  3. while($row=mysql_fetch_array($result, MYSQL_NUM)){
  4. echo '<b>tytul: </b>'.$row[1].'<b> Drugi tytul: </b>'.$row[2].'<b> Autorzy: </b>';
  5. $query2="SELECT t_author.name , t_author.surname , t_author.id_author FROM t_author, t_book_author WHERE t_book_author.f_book='".$row[0]."' AND t_author.id_author=t_book_author.f_author";
  6. $result2=mysql_query($query2);
  7. while($row2=mysql_fetch_array($result2,MYSQL_NUM)){
  8. $query3="SELECT t_title.title FROM t_title , t_author_title WHERE t_title.id_title=t_author_title.f_title AND t_author_title.f_author='".$row2[2]."'";
  9. $result3=mysql_query($query3);
  10. while($row3=mysql_fetch_array($result3,MYSQL_NUM)){
  11. echo"$row3[0] ";
  12. }
  13. echo $row2[0].','.$row2[1].'<br>';
  14. }
  15. echo'<br><br>';
  16.  
  17.  
  18. }
Wszystko wygląda i działa super. Ale domyślam się, że zamierzony (powyższy) efekt można osiągnąć jednym poprawnie skonstruowanym zapytaniem. I tu właśnie ponawiam zapytanie do Was: DA SIĘ?

Dzięki.
thek
Wcale nie wyklucza. Wystarczy, że w tabeli umieścisz je jako jedną z możliwości. Mgr, mgr inż. i inż to były by 3 osobne warianty. Dlatego pisałem o kombinacjach tytułów. Ich naprawdę nie ma aż tyle, by rozbijać to na kilka tabel i potem jeszcze je JOINować. Tylko niepotrzebnie dokładasz złączenie w zapytaniu. t_title i t_author_title śmiało mogą być jedną tabelą i w takim wypadku zmieni Ci się relacja na poziomie t_author i t_author_title. A wyszukiwanie zmieni ci się niewiele. Dlaczego niewiele? Bo tylko o tyle, że będziesz musiał znać przy szukaniu inżyniera gdzie jest inż, mgr inż, dr inż, prof. dr hab. inż. i tego typu. To samo z innymi tytułami. Wyszukiwanie więc będzie nie po jednym id określającym tytuł (WHERE id=1), ale kilku (WHERE id IN (1,4,5,6) ). Całość grupowana jest oczywiście po id książki, ale GROUP_CONCAT na autorach to przecież w takim wypadku już nie problem chyba winksmiley.jpg

EDIT: Poprawka literówek. Nienawidzę pisania z kompa dziewczyny. Połowę klawiszy muszę walić chyba młotkiem bo nie reagują. Nawet spacja działa ze skutecznością 50% :/
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.