Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: problem ze sfromuowaniem zapytania
Forum PHP.pl > Forum > Bazy danych > MySQL
hmmm
mam problem ze sformuowaniem zapytania ...

mam dwie tabele:
1. kategorie
- id
- kategoria (np. 'niemiecki', 'programy')
2. download
- id
- kategoria (numery odpowiadajace dla kategorie.id)
- plik (nazwa pliku)
- nazwa (opis pliku)
- wielkosc

chcialbym teraz za pomoca najchetniej jednego zapytania, jezeli sie nie da, to dwoch (przypuszczam, ze petla w petli) wyswietlic to w takiej formie:

Kod
nazwa_kategorii1:
nazwa_pliku  |  opis_pliku  |  wielkosc_pliku
nazwa_kategorii2:
nazwa_pliku  |  opis_pliku  |  wielkosc_pliku
i tak dalej

czyli podzielic najpierw na kategorie i pod nazwa kazdej kategorii wyswietlic pliki nalezace do tej kategorii.
probowalem, ale nie wychodzi.
wszystko bylo dobrze, dopoki mialem jedna tabele - kategorie i zamiast wartosci liczbowych w kolumnie kategorie mialem nazwy kategorii.
patigo
napisz to co sam wymyśliłeś, mam pewną propozycję ale chciałbym zobaczyć twój tok myślenia
hmmm
sorki, ze dopiero, ale probowalem jeszcze cos stworzyc i ostetecznie, zupelnie sie pogubilem.
mam tylko moje pierwsze rozwiazanie, reszta przepadla razem w probami, bo nie zapisuje tych, ktore i tak sa zle ...

na poczatku robilem to tak:
mialem wowczas jedna tabele - download i w niej byla kolumna kategoria, do ktorej wpisywalem wartosci liczbowe, np. 1,2,3,4,...

a potem mialem taki skrypcik php:
  1. <?php
  2. $kategorie = array(1 => 'matematyka', 'niemiecki', 'do pobrania', 'skrypty');
  3. // wartosci tablicy $kategorie
  4. // 1 => matematyka
  5. // 2 => niemiecki
  6. // 3 => do pobrania
  7. // 4 => skrypty
  8.  
  9. // pobierz wszystkie grupy plikow
  10. $polecenie2 = mysql_query(&#092;"SELECT kategoria FROM download GROUP BY kategoria\");
  11. while ($wynik2 = mysql_fetch_array($polecenie2, MYSQL_NUM)) {
  12. $download_grupy[] = $wynik2[0];
  13. }
  14.  
  15. // wyswietl wszystkie grupy plikow
  16. foreach ($download_grupy as $download_grupa) {
  17.  
  18. ?>
  19. <table class=\"download\" cellspacing=\"0\" cellpadding=\"0\">
  20. <tr>
  21. <td class=\"td2\" colspan=\"2\">
  22. <?=$kategorie[$download_grupa] . &#092;"n\";?>
  23. </td>
  24. </tr>
  25. <?php
  26.  
  27. // pobierz wszystkie pliki dla danej grupy plikow
  28. // wyswietl wszystkie pliki dla danej grupy plikow
  29. $polecenie3 = mysql_query(&#092;"SELECT plik, nazwa, wielkosc FROM download WHERE kategoria = '\" . $download_grupa . \"'\");
  30. $download_numer = 1;
  31. while ($wynik3 = mysql_fetch_array($polecenie3, MYSQL_NUM)) {
  32. ?>
  33. <tr>
  34. <td class=\"td1\">
  35. <?=$download_numer++;?>.
  36. </td>
  37. <td class=\"td2\">
  38. <a href=\"download/<?=$wynik3[0];?>\"><?=$wynik3[1];?> <span class=\"szary\">[<?=$wynik3[2];?>KB]</span></a>
  39. </td>
  40. </tr>
  41. <?php
  42. }
  43. mysql_free_result($polecenie3);
  44.  
  45. echo &#092;"t\" . '</table>' . \"n\";
  46. ?>
prymitywnie - wiem.

chce to zrobic lepiej, ale nie moge sobie poradzic ...
bigZbig
Proponuje abys zrobil takie zapytanie


  1. <?php
  2. $query=&#092;"SELECT kat.kategoria as 'nazwa_kategorii', plik as 'nazwa_pliku', nazwa as 'opis_pliku', wielkosc as 'wielkosc_pliku'
  3. FROM kategorie as 'kat', download as 'down' 
  4. WHERE down.kategoria = kat.id;&#092;";
  5. ?>



Tak na marginesie, kto ci wymyslil takie nazwy tabel i pol w tabelach?

Nie prosciej byloby:

kategorie
1. id_kategorie //najlepiej aby nazwa klucza podstawowego zawierala nazwe tabeli
2. nazwa //albo nazwa_kategorii

pliki
1. id_pliki
2. id_kategorie //od razu widac ze to jest klucz obcy
3. nazwa
4. opis
5. wielkosc
hmmm
to znaczy, to co podalem w pierwszym poscie - nazwy tabel i kolumn, to czytac nalezy bez tych nawiasow.
to, ze dobrze jest nazywac klucze obce i glowne np. id_kategorie, to wiem, no ale tak jakos sobie utrudniam zawsze tongue.gif

no ale zmienilem juz nazwy kolumn:
download:
- id
- kategoria
- nazwa
- opis
- wielkosc
kategorie:
- id
- kategoria

twoje zapytanie dziala i nawet je rozumiem, ale nie wiem, jak mam je wykorzystac, aby wyswietlic je juz na stronie w takiej formie, jakbym chcial.
poza tym, zwraca mi wszystkie rekordy, nie wiem, czy o to chodzi ...
w formie uproszczonej chodzi mi o cos takiego:
Kod
nazwa kategorii1
wyswietlenie wszystkich plikow z tej kategorii

nazwa kategorii2
wyswietlenie wszystkich plikow z tej kategorii

itd.
nie wiem, jak to zrobic w php.
w tabelke wsadzic to zaden problem, ale nie wiem, jak wyswietlic sadsmiley02.gif


E D I T :
wymyslilem cos, tylko zastanawiam sie, czy mozna to jakos skrocic.
ja niestety nie mam zadnych pomyslow ...
  1. <?php
  2. include('katalog/plik.inc');
  3. $db = mysql_connect($host, $user, $pass);
  4. mysql_select_db($name, $db);
  5.  
  6. // zliczam ilosc rekordow w tabeli kategorie
  7. // i tworze tablice z id wszystkich kategorii
  8. $polecenie3 = mysql_query(&#092;"SELECT count(id), id FROM kategorie GROUP BY id ORDER BY kategoria\");
  9. while ($wynik3 = mysql_fetch_array($polecenie3, MYSQL_NUM)) {
  10. $download_ilosc = $wynik3[0];
  11. $kategorie[] = $wynik3[1];
  12. }
  13.  
  14. if ($download_ilosc > 0) {
  15.  
  16. echo &#092;"t\" . '<table id=\"download\" cellspacing=\"0\" cellpadding=\"0\">' . \"n\";
  17.  
  18. // funckja tworzaca linki do plikow
  19. function plik ($zmienna1, $zmienna2, $zmienna3) {
  20. return '<a href=\"download/' . $zmienna1 . '\">' . $zmienna2 . ' <span class=\"szary\">[' . $zmienna3 . 'KB]</span></a>';
  21. }
  22.  
  23. // wyswietlenie wszystkich rodzajow kategorii
  24. foreach ($kategorie as $pokaz) {
  25. // pobieram odpowiednia nazwe kategorii dla danego id
  26. $polecenie4 = mysql_query(&#092;"SELECT kategoria FROM kategorie WHERE id = $pokaz\");
  27. while ($wynik4 = mysql_fetch_array($polecenie4, MYSQL_NUM)) {
  28. $kategoria = $wynik4[0];
  29. }
  30. ?>
  31. <tr>
  32. <td class=\"td2\" colspan=\"2\">
  33. <?=$kategoria . &#092;"n\";?>
  34. </td>
  35. </tr>
  36. <?php
  37. // pobieram wartosci dla kazdego pliku
  38. // i wyswietlam je
  39. $polecenie5 = mysql_query(&#092;"SELECT nazwa, opis, wielkosc FROM download WHERE download.kategoria = $poka
    z\");
  40. $numer = 1;
  41. while ($wynik5 = mysql_fetch_array($polecenie5, MYSQL_NUM)) {
  42. ?>
  43. <tr>
  44. <td class=\"td1\">
  45. <?=$numer++;?>.
  46. </td>
  47. <td class=\"td2\">
  48. <?=plik($wynik5[0], $wynik5[1], $wynik5[2]);?>
  49. </td>
  50. </tr>
  51. <?php
  52. }
  53. }
  54.  
  55. echo &#092;"t\" . '</table>' . \"n\";
  56.  
  57. } else {
  58. ?>
  59. <div id=\"download\">
  60.  
  61. jak dotad brak wpisow w ksiedze gosci.
  62.  
  63. </div>
  64. <?php
  65. }
  66. ?>
bigZbig
Wiekszosc zadan mozna wykonac na wiele roznych sposobow. Dobrze jest jezeli masz zoptymalizowany kod, ale jeszcze lepiej jesli to jest Twoj kod - nawet gdy nie jest w pelni profesjonalny. Piszac cos samemu uczysz sie o wiele szybciej niz wtedy gdy kozystasz z gotowych, cudzych rozwiazan.

Co do zademonstrowanego przez Ciebie fragmentu kodu mam jednak kilka uwag.
  1. <?php
  2.  
  3. $polecenie3 = mysql_query(&#092;"SELECT count(id), id FROM kategorie GROUP BY id ORDER BY kategoria\");
  4. while ($wynik3 = mysql_fetch_array($polecenie3, MYSQL_NUM)) {
  5. $download_ilosc = $wynik3[0];
  6. $kategorie[] = $wynik3[1];
  7. }
  8.  
  9. if ($download_ilosc > 0) {
  10.  
  11. ?>

Wykonywanie wbudowanej funkcji count() na kluczu podstawowym z uzyta klauzula GROUP BY na tym samym parametrze mija sie z celem poniewaz, jak w dym mozesz przyjac ze wyjdzie 1 (w koncu wartosci klucza podstawowego sa unikalne), no chyba, ze tabela jest pusta. Co za tym idzie warunek "if ($download_ilosc > 0)" jest bez sensu bo jesli tylko zapytanie zwroci wynik to ten warunek jest zawsze prawdziwy. Proponuje to zastapic kodem
  1. <?php
  2.  
  3. $polecenie3 = mysql_query(&#092;"SELECT id FROM kategorie ORDER BY kategoria\");
  4. if ($polecenie3==true) {
  5. while ($wynik3 = mysql_fetch_array($polecenie3, MYSQL_NUM)) {
  6.  $kategorie[] = $wynik3[0]; 
  7. }
  8. ?>

Jesli zamiast MYSQL_NUM uzylbys MYSQL_ASSOC dzialal by zapis:
$kategorie[] = $wynik3['id'];

Jesli uzylbys MYSQL_BOTH, ktory jest wartoscia domyslna
oba zapisy moglbys stosowac zamiennie, jak wygodniej.

Musisz koniecznie ale to naprawde koniecznie popracowac nad wlasciwym nadawaniem nazw funkcji i zmiennym bo w przeciwnym razie szybko sie pogubisz w swoim wlasnym projekcie.
  1. <?php
  2. function plik ($zmienna1, $zmienna2, $zmienna3)
  3. ?>

Nazwa funkcji powinna zawierac jakis czasownik bo przeciez funkcja cos robi, a ta konkretna funkcja tworzy link. Nazwij ja wiec np. tworzLink(). Poza tym co przechowuja zmienne: $zmienna1, $zmienna2, $zmienna3? Nazwa zmiennej powinna odzwierciedlac jej zawartosc.
  1. <?php
  2. foreach ($kategorie as $pokaz) {
  3. // pobieram odpowiednia nazwe kategorii dla danego id
  4. $polecenie4 = mysql_query(&#092;"SELECT kategoria FROM kategorie WHERE id = $pokaz\");
  5. ?>

Rozumiem, ze tablice w ktorej przechowujesz identyfikatory kategorii nazwales $kategorie ale dlaczego uzyles nazwy $pokaz dla zmiennej, ktora przechowuje pojedynczy identyfikator kategorii? Poza tym Twoj komentarz jest nieprawdziwy bo ty nie pobierasz nazw kategorii tylko identyfikatory kategorii, a tak na marginesie gdybys mial dobrze dobrane nazwy zmiennych to akurat w tym wypadku komentarz bylby zbedny.
hmmm
dziekuje za wszystkie uwagi smile.gif
nauka nie pojdzie w pole i na pewno skorzystam z niej.

mam tylko jedno zastrzezenie do podanych przez ciebie rozwiazan, mianowicie do pierwszego. napisales warunek
  1. <?php
  2. if ($polecenie3==true)
  3. ?>
ale mi nie chodzi o to, czy polecenie wykona, czy nie, tylko o ilosc elementow w tablicy i zaleznosci od tego, ma wyswietlic albo kategorie i pliki, albo wiadomosc, ze nie ma zadnych plikow.
nie wiem, czy dobrze kombinuje, ale jezeli ilosc id bedzie rowna zero, czyli nie bedzie kategorii, a polecenie zostanie wykonane to i tak $polecenie3 bedzie rownalo sie true.
napisalem cos takiego:
  1. <?php
  2. $polecenie3 = mysql_query(&#092;"SELECT id FROM kategorie ORDER BY kategoria\");
  3. while ($wynik3 = mysql_fetch_array($polecenie3, MYSQL_NUM)) {
  4. $kategorie[] = $wynik3[0];
  5. }
  6. $ilosc_kategorii = count($kategorie);
  7. if ($ilosc_kategorii > 0) {
  8. // wyswietl wszystkie kategorie i pliki do nich nalezace
  9. } else {
  10. echo 'jak dotad brak plikow w bazie.';
  11. }
  12. ?>

z dalszej lektory rozumiem, ze wcale nie musze pisac MYSQL_NUM, tylko nazwe zmiennej i potem w petli while bede sie odwolywal albo do nazw, albo do numerow ...

a to nowy, poprawiony skrypt:
  1. <?php
  2. include('katalog/plik.inc');
  3. $db = mysql_connect($host, $user, $pass);
  4. mysql_select_db($name, $db);
  5.  
  6. // zlicz ilosc rekordow w tabeli kategorie
  7. // utworz tablice zawierajaca id wszystkich kategorii
  8. $polecenie3 = mysql_query(&#092;"SELECT id FROM kategorie ORDER BY kategoria\");
  9. while ($wynik3 = mysql_fetch_array($polecenie3, MYSQL_NUM)) {
  10. $kategorie[] = $wynik3[0];
  11. }
  12. mysql_free_result($polecenie3);
  13.  
  14. // zlicz ilosc wszystkich kategorii
  15. $ilosc_kategorii = count($kategorie);
  16. if ($ilosc_kategorii > 0) {
  17.  
  18. echo &#092;"t\" . '<table id=\"download\" cellspacing=\"0\" cellpadding=\"0\">' . \"n\";
  19.  
  20. // funckja tworzaca linki do plikow
  21. function tworzlink ($nazwa_pliku, $opis_pliku, $wielkosc_pliku) {
  22. return '<a href=\"download/' . $nazwa_pliku . '\">' . $opis_pliku . ' <span class=\"szary\">[' . $wielkosc_pliku . 'KB]</span></a>';
  23. }
  24.  
  25. // wyswietl wszystkie rodzaje kategorii
  26. foreach ($kategorie as $id) {
  27. // pobierz odpowiednia nazwe kategorii dla danego id
  28. $polecenie4 = mysql_query(&#092;"SELECT kategoria FROM kategorie WHERE id = $id\");
  29. while ($wynik4 = mysql_fetch_array($polecenie4, MYSQL_NUM)) {
  30. $kategoria = $wynik4[0];
  31. }
  32. mysql_free_result($polecenie4);
  33. ?>
  34. <tr>
  35. <td class=\"td2\" colspan=\"2\">
  36. <?=$kategoria . &#092;"n\";?>
  37. </td>
  38. </tr>
  39. <?php
  40. // pobierz wartosci dla kazdego pliku i wyswietl je
  41. $polecenie5 = mysql_query(&#092;"SELECT nazwa, opis, wielkosc FROM download WHERE download.kategoria = $id\");
  42. $numer = 1;
  43. while ($wynik5 = mysql_fetch_array($polecenie5, MYSQL_NUM)) {
  44. ?>
  45. <tr>
  46. <td class=\"td1\">
  47. <?=$numer++;?>.
  48. </td>
  49. <td class=\"td2\">
  50. <?=tworzlink($wynik5[0], $wynik5[1], $wynik5[2]);?>
  51. </td>
  52. </tr>
  53. <?php
  54. }
  55. mysql_free_result($polecenie5);
  56. }
  57.  
  58. echo &#092;"t\" . '</table>' . \"n\";
  59.  
  60. } else {
  61. ?>
  62. <div id=\"download\">
  63.  
  64. jak dotad brak plikow w bazie.
  65.  
  66. </div>
  67. <?php
  68. }
  69.  
  70. ?>
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.