Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Łaczenie wyników - dwie tabele - dobre praktyki
Forum PHP.pl > Forum > Bazy danych > MySQL
Sokon
Sytuacja wygląda następująco, dużo czytałem o tym jak się nie powinno robić ale nigdzie jak się powinno.

Przykładowo mam dwie tabele:
1. Kliniki
2. Usługi

Tabela kliniki ma PK o nazwie klinikaId
Tabela usługi ma FK do tabeli kliniki o nazwie klinikaId

Jedna klinika ma w ofercie wiele usług jak pobrać poprawnie dane z obu tabel żeby nie zagnieżdżać zapytania w zapytaniu w taki sposób (będę pisał skrótami):
  1. <?php
  2. $zapytanie1 = mysql_query( 'SELECT * FROM `kliniki`' );
  3. while( $wynik1 = mysql_fetch_array( $zapytanie1 ) ) {
  4. echo 'wyniki zapytania o kliniki';
  5. $zapytanie2 = mysql_query( 'SELECT * FROM `usługi` WHERE `klinikaId`='.$wynik1['klinikaId'].'' );
  6. while( $wynik2 = mysql_fetch_array( $zapytanie2 ) ) {
  7. echo 'wyniki zapytania o usługi';
  8. }
  9. }
  10. ?>
luckyps
Poczytaj o join w zapytaniach.
Sokon
Ok, napiszę bardziej precyzyjnie. Czy da się zapytać tak aby pod wynikiem danej kliniki mieć wy listowane jej usługi:
Klinika 1
Usługa 1
Usługa 3
Usługa 5

Klinika 2
Usługa 1
Usługa 2
Usługa 3

Klinika 3
Usługa 1
Usługa 2
Usługa 3

I tak dalej, usługi są pobierane ze słownika.

O ile znam JOIN, to mogę albo dostać iloczyn kartezjański nie stosując GROUP BY albo mogę mogę użyć GROUP BY po id kliniki i nie dostać pełnej listy usług.
nospor
Pisałem o tym
http://nospor.pl/grupowanie-wynikow.html
Sokon
No masz Pan, wczoraj przeglądałem Twoją stronkę, zaciekawił mnie art. o generowaniu linków i tego nie zauważyłem.

Dzięki.

Nie wiem czy dobrze, że tu zamieszczam a nie nowy temat tworzę, ale to w sumie w ramach starego jest, jakby co to założę nowy.
Do rzeczy, posiedziałem trochę i spłodziłem coś takiego, generalnie działa tak jak chciałem żeby działało ale mam wrażenie, że coś przegapiłem.
Krótkie wprowadzenie:
Skrypt wyszukiwarki, mamy trzy okienka na stronie, województwa (provinces), miasta (cities), usługi (services), po wejściu na stroną od razu ładują się województwa, po wybraniu jednego lub kilku województw w okienku miast pokazują się te miasta które należą do wybranych województw, jeszcze obok jest lista ikonek reprezentujących usługi, można wybrać jakieś usługi lub nie, warunek jest taki, że zawsze musi być wybrane przynajmniej jedno województwo inaczej wywali komunikat o zawężeniu kryteriów wyszukiwania, reszta jest opcjonalna.
Po wybraniu odpowiednich kryteriów, za pomocą jquery (ajaxa) przekazuję (GET'em) zmienne dotyczące województw, miast lub usług do pliku ze skryptem poniżej a wyniki ładuję w DIV'a. Teraz moje pytanie czy waszym zdaniem przyjęty sposób sprawdzania poprawności w/w zmiennych (preg_match()) jest wystarczający, czy może coś jeszcze dopisać, druga sprawa to czy coś byście zmienili w samym zapytaniu lub sposobie jego generowania.

Docelowo zmienne są przekazywane GET'em ale poniżej zamieszczam skrypt testowy i odpowiednikiem tych zmiennych są zmienne $p (województwa), $c (miasta), $s (usługi) - to tak jakby ktoś się pytał.

  1. <span style="font: normal 10pt Arial;">
  2. <?php
  3. require_once( "../configure.php" );
  4. //$p = '1|2|';
  5. $c = '50|51|';
  6. //$s = '1|2|';
  7.  
  8. $provincesArray = explode( "|", $p );
  9. $citiesArray = explode( "|", $c );
  10. $servicesArray = explode( "|", $s );
  11.  
  12. foreach( $provincesArray as $provinceId ) {
  13. if( !isset( $province ) ) {
  14. if( preg_match( '/^[0-9]{1,2}$/', $provinceId ) == TRUE ) $province = '`dc`.`provinceId` = '.$provinceId;
  15. } else {
  16. if( preg_match( '/^[0-9]{1,2}$/', $provinceId ) == TRUE ) $province .= ' || `dc`.`provinceId` = '.$provinceId;
  17. }
  18. }
  19.  
  20. foreach( $citiesArray as $cityId ) {
  21. if( !isset( $city ) ) {
  22. if( preg_match( '/^[0-9]{1,9}$/', $cityId ) == TRUE ) $city = '`dc`.`cityId` = '.$cityId;
  23. } else {
  24. if( preg_match( '/^[0-9]{1,9}$/', $cityId ) == TRUE ) $city .= ' || `dc`.`cityId` = '.$cityId;
  25. }
  26. }
  27.  
  28. foreach( $servicesArray as $serviceId ) {
  29. if( !isset( $service ) ) {
  30. if( preg_match( '/^[0-9]{1,2}$/', $serviceId ) == TRUE ) $service = '`cse`.`serviceId` = '.$serviceId;
  31. } else {
  32. if( preg_match( '/^[0-9]{1,2}$/', $serviceId ) == TRUE ) $service .= ' || `cse`.`serviceId` = '.$serviceId;
  33. }
  34. }
  35.  
  36.  
  37. if( $province == "" && $city == "" ) {
  38. echo '<h1 class="header">Błąd wyszukiwania!</h1><p class="body">Należy zawęzić kryteria wyszukiwania.</p>';
  39. } else {
  40. if( $city == "" ) {
  41. $location = $province;
  42. } else {
  43. $location = $city;
  44. }
  45.  
  46. if( $service == "" ) {
  47. $services = '
  48. LEFT JOIN (
  49. SELECT
  50. `cse`.`cbdId`,
  51. `wds`.`title`,
  52. `wds`.`class`
  53. FROM `WWS_CL_SE` cse, `WWS_DICT_SERVICES` wds, `WWS_CL_ED` wce
  54. WHERE `cse`.`cbdId` = `wce`.`cbdId`
  55. AND `wds`.`serviceId` = `cse`.`serviceId`
  56. AND `wce`.`expires` > NOW()
  57. ) AS `ser` ON ( `cbd`.`cbdId` = `ser`.`cbdId` )
  58. ';
  59. } else {
  60. $services = '
  61. INNER JOIN (
  62. SELECT
  63. `cse`.`cbdId`,
  64. `wds`.`title`,
  65. `wds`.`class`
  66. FROM `WWS_CL_SE` cse, `WWS_DICT_SERVICES` wds, `WWS_CL_ED` wce
  67. WHERE ( '.$service.' )
  68. AND `cse`.`cbdId` = `wce`.`cbdId`
  69. AND `wds`.`serviceId` = `cse`.`serviceId`
  70. AND `wce`.`expires` > NOW()
  71. ) AS `ser` ON ( `cbd`.`cbdId` = `ser`.`cbdId` )
  72. ';
  73. }
  74.  
  75. $selectQuery = $db->prepare( '
  76. SELECT
  77. `cbd`.`cbdId`,
  78. `cbd`.`cityId`,
  79. `cbd`.`name`,
  80. `cbd`.`street`,
  81. `cbd`.`postal`,
  82. `loc`.`city`,
  83. `loc`.`province`,
  84. `cbd`.`phone1`,
  85. `ced`.`www`,
  86. `ced`.`emails`,
  87. `ced`.`phones`,
  88. `ced`.`open`,
  89. `ser`.`title`,
  90. `ser`.`class`
  91. FROM `WWS_CL_BD` cbd
  92.  
  93. LEFT JOIN (
  94. SELECT
  95. `ced`.`cbdId`,
  96. `ced`.`www`,
  97. `ced`.`emails`,
  98. `ced`.`phones`,
  99. `ced`.`open`
  100. FROM `WWS_CL_ED` ced
  101. WHERE `ced`.`expires` > NOW()
  102. ) AS `ced` ON ( `cbd`.`cbdId` = `ced`.`cbdId` )
  103.  
  104. '.$services.'
  105.  
  106. INNER JOIN (
  107. SELECT
  108. `dc`.`cityId`,
  109. `dc`.`name` AS `city`,
  110. `dp`.`short_name` AS `province`
  111. FROM `WWS_DICT_CITIES` dc, `WWS_DICT_PROVINCES` dp
  112. WHERE `dc`.`provinceId` = `dp`.`provinceId`
  113. AND ( '.$location.' )
  114. ) AS `loc` ON ( `cbd`.`cityId` = `loc`.`cityId` )
  115. ' );
  116.  
  117. $selectQuery->execute();
  118.  
  119. $clinics = array();
  120. while( $resultQuery = $selectQuery->fetch( PDO::FETCH_ASSOC ) ) {
  121. $cbdId = $resultQuery['cbdId'];
  122. if( !isset( $clinics[$cbdId] ) ) {
  123. $clinics[$cbdId] = array(
  124. 'name' => $resultQuery['name'],
  125. 'street' => $resultQuery['street'],
  126. 'postal' => $resultQuery['postal'],
  127. 'city' => $resultQuery['city'],
  128. 'province' => $resultQuery['province'],
  129. 'phone1' => $resultQuery['phone1'],
  130. 'www' => $resultQuery['www'],
  131. 'services' => array()
  132. );
  133. }
  134.  
  135. if( !empty( $resultQuery['title'] ) ) {
  136. $clinics[$cbdId]['services'][] = array(
  137. 'class' => $resultQuery['class'],
  138. 'title' => $resultQuery['title']
  139. );
  140. }
  141. }
  142.  
  143. //echo $city.'<br />'.$province.'<br />'.$service;
  144. foreach( $clinics as $clinicId => $clinic ) { //petla, która leci po klinikach
  145. echo '<h1>'.$clinic['name'].'</h1>';
  146. echo '<p>'.$clinic['street'].'</p>';
  147. echo '<p>'.$clinic['postal'].', '.$clinic['city'].'</p>';
  148. echo '<p>woj. '.$clinic['province'].'</p>';
  149. echo '<p>'.$clinic['phone1'].'</p>';
  150. if( $clinic['www'] != "" ) echo '<p>'.$clinic['www'].'</p>';
  151. if( $clinic['services'] != "" ) {
  152. echo '<p>Usługi ('.count($clinic['services']).')</p>';
  153. echo '<ul>';
  154. foreach( $clinic['services'] as $service ) { //pętla, która leci po usługach
  155. echo '<li>'.$service['title'].' - '.$service['class'].'</li>';
  156. }
  157. echo '</ul>';
  158. }
  159. }
  160. }
  161. ?>
  162. </span>


Edited
No i co ? I dupa!
Przetestowałem dokładniej i znalazłem błąd, jak wybieram jedną usługę to pokazuje klinikę a dla niej tą jedną usługą nawet jak klinika ma ich więcej pokazuje tylko tą wybraną.

Kurde męczę się i męczę, pomocy ....
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.