Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [MySQL][PHP]wyszukiwarka z parametrem IN
Forum PHP.pl > Forum > Przedszkole
Stron: 1, 2
peklo
właśnie chyba lepiej żeby było jak np szukam A,B to żeby rzeczywiscie pokazało mi rekord z A,B
Bo teraz jest tak że jak zaznacze A,B,C to pokazuje rekord z A lub A,B a nie uwzglednia tego C

Jak zaznaczę wymagane prawo jazdy od A do T czyli 15 sztuk to wyświetli mi wszystkie rekordy, a takich rzeczywiście rekordów w bazie może być tylko 1

Tj tak jak np na allegro. jak dodaje dodatkowe wyposażenie to wyswietla mi się coraz mniej pojazdów
trueblue
W takim razie to nie może być operator IN smile.gif
peklo
o kurde nie osłabiaj smile.gif to znowu cały kod do zmiany?
Chodzi mi o to że jak ktos wymaga prawa jazdy kat np B,B+E to lepiej żeby tak sie pokazało. Bo tak to pokaże mi oddzielne rekordy z B i B+e lub itd
trueblue
Zamień linijkę 30-33 na:
  1. $where_idpj[]='id_prawo_jazdy=:id_prawo_jazdy_'.$i;
  2. $bind[':id_prawo_jazdy_'.$i++]=$idpj;
  3. }
  4. $where[] = implode(' AND ',$where_idpj);
peklo
coś nie halo
bo jak zaznacze a,a1 to pokazuje mi a lub a1, a mam w rekordzie a,a1 i go nie wyświetla
trueblue
Pokaż przykładowy rekord.
peklo
rekodr nr 66 AM,A1
trueblue
To Ty masz w jednym polu zapisane jednocześnie wszystkie możliwe id_prawo_jazdy?
Jaki typ ma to pole?
peklo
tinyint

mam tak że w tabeli glównej dla id np 66 pobiera wszystkie rekordy z tabeli prawa jazdy gdzie id_dodatkowe=66.
I teraz id_prawo_jazdy jest rowniez tinyint

np: id_dodatkowe , id_prawo_jazdy
66 , 1
66 , 7
66 , 10 itd

a to jest źle?
trueblue
Bardzo dobrze.

Czyli jeśli zaznaczysz dwa typy prawa jazdy, to nie wybiera rekordów dokładnie z tymi dwoma typami, lecz z którymkolwiek z nich, tak?
peklo
dokładnie tak A,B to wybiera mi A lub B a nie (A z B,)

generalnie w tabeli prawa jazdy mam takie pola
id int
id_powiazane int
id_prawa_jazdy tinyint

A może trzeba zrobić grupowanie wyników żeby wyświetlało prawidłowo rekordy na stronie?
trueblue
Zmień linijkę z zapytaniem na:
  1. $sql="SELECT o.miasto,o.id_kategoria,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN pj p on o.id=p.id_ogloszenia WHERE ". implode( ' AND ', $where )." group by o.id order by o.id DESC";
  2. $stmt = $pdo->prepare($sql);

i daj echo $sql; za nimi. Pokaż jak to zapytanie wygląda.
peklo
SELECT o.miasto,o.id_kraj,o.id_wojewodztwo,o.wyroznione,o.aktywne,o.id,o.za,o.cena,o.id
_kategoria,o.data_dod,o.nazwa_ogloszenia,o.czas, z.id_ogloszenia,z.thumb,z.uploads,z.im,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN zdjecia z on o.id=z.id_ogloszenia LEFT OUTER JOIN pj p on o.id=p.id_ogloszenia WHERE aktywne = :aktywne AND id_kategoria = :id_kategoria group by o.id order by o.id DESC

jak zaznacze prawo jazdy i szukaj AM,A1 to:
SELECT o.miasto,o.id_kraj,o.id_wojewodztwo,o.wyroznione,o.aktywne,o.id,o.za,o.cena,o.id
_kategoria,o.data_dod,o.nazwa_ogloszenia,o.czas, z.id_ogloszenia,z.thumb,z.uploads,z.im,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN zdjecia z on o.id=z.id_ogloszenia LEFT OUTER JOIN pj p on o.id=p.id_ogloszenia WHERE aktywne = :aktywne AND id_kategoria = :id_kategoria AND id_prawo_jazdy=:id_prawo_jazdy_0 AND id_prawo_jazdy=:id_prawo_jazdy_1 group by o.id order by o.id DESC
trueblue
Pokazałeś zapytanie chyba bez zaznaczonych checkboxów, ale ok.
Czy aby na pewno tam powinno być?
  1. LEFT OUTER JOIN pj p ON o.id=p.id_ogloszenia
peklo
id w tabeli głównej ma np 66

Tabela prawa_jazdy
id_ogloszenia=66 gdzie w id_prawo_jazdy ma dwa rekordy 1,2

może inaczej
dla id głownego istnieja dwa rekordy w tabeli prawa_jazdy

tak LEFT OUTER JOIN pj p ON o.id=p.id_ogloszenia
mam w podglądzie karty i wyswietla ok
trueblue
smile.gif

Pokaż sql według metody, o której pisałem wyżej, tyle, że przy jednak zaznacz mininum 2 checkboxy.
peklo
tj wyżej
zaszaleja. masz nawet 4 smile.gif

AND id_prawo_jazdy=:id_prawo_jazdy_0 AND id_prawo_jazdy=:id_prawo_jazdy_1 AND id_prawo_jazdy=:id_prawo_jazdy_2 AND id_prawo_jazdy=:id_prawo_jazdy_3 group by o.id order by o.id DESC
trueblue
Jest ok, dzięki.

Ale ja się zgubiłem. Zaznacz takie prawo jazdy jakie ma jakiś wybrany rekord, najlepiej aby był to jedyny rekord, który ma przypisane takie id_prawo_jazdy.
Czy wtedy wyszukiwarka pokazuje Ci również inne rekordy?
peklo
Trueblue muszę Cię przeprosić bo musze iść z dzieckiem na dwór. Będe później. Odblokuj pocztę bo albo masz pełną albo zablokowałeś wiadomości

to jest zapytanie dla id=66
SELECT o.miasto,o.id_kraj,o.id_wojewodztwo,o.wyroznione,o.id,o.za,o.cena,o.id_kategoria
,o.data_dod,o.nazwa_ogloszenia,o.czas, z.id_ogloszenia,z.thumb,z.uploads,z.im,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN zdjecia z on o.id=z.id_ogloszenia LEFT OUTER JOIN pj p on o.id=p.id_ogloszenia WHERE aktywne = :aktywne AND id_kategoria = :id_kategoria AND id_prawo_jazdy=:id_prawo_jazdy_0 AND id_prawo_jazdy=:id_prawo_jazdy_1 group by o.id order by o.id DESC

dla id=66 mam jeden warunek z AM,A1. Jeśli zaznacze AM,A1 w checkbox to nie pokazuje nic. Jeśli AM lub A1 to pokazuje mi te rekordy dla których jest spełniony warunek np dla AM
trueblue
Nie wiem jak zniosę tą rozłąkęsmile.gif

PW zablokowałem.
peklo
ok już jestem. A może chodzi o to nieszczęsne grupowanie wynikow na stronie?
trueblue
Czy na pewno id_ogloszenie=66 ma przyporządkowane id_prawo_jazdy=2?
peklo
zaraz wejde w konsole i sprawdze
tak
1,2 id_ogloszenia
trueblue
Cytat(peklo @ 7.05.2014, 17:19:16 ) *
1,2 id_ogloszenia

Czy id_prawo_jazdy?


Wykonaj bezpośrednio na bazie danych zapytanie:
  1. SELECT o.miasto,o.id_kraj,o.id_wojewodztwo,o.wyroznione,o.id,o.za,o.cena,o.id_kategoria
  2. ,o.data_dod,o.nazwa_ogloszenia,o.czas, z.id_ogloszenia,z.thumb,z.uploads,z.im,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN zdjecia z ON o.id=z.id_ogloszenia LEFT OUTER JOIN pj p ON o.id=p.id_ogloszenia WHERE aktywne=1 AND id_kategoria=1 AND id_prawo_jazdy=1 AND id_prawo_jazdy=2 GROUP BY o.id ORDER BY o.id DESC

Aktywne=1 - nie wiem gdzie to bindujesz, więc zakładam, że ma być 1.

Otrzymałeś ogłoszenie id=66?

peklo
ups brak wyniku
trueblue
A czy na pewno łączysz tablice po poprawnych kolumnach?

W zrzucie powyżej widać id i jest również id_ogloszenia.
W zapytaniu łączysz o.id z p.id_ogloszenia.
Które pole to id ogłoszenia?
nospor
No dobra, wtrace sie na chwilke bo nie moge patrzyc jak kluczycie nie widzac oczywistej oczywistosci....

AND id_prawo_jazdy=1 AND id_prawo_jazdy=2
A wiec Panowie, dany rekord nie moze zawierac jednoczesnie wartosci 1 i wartosci 2, dlatego tez, to zapytanie zawsze zwroci pusty wynik. Mam nadzieje ze oswiecilem smile.gif
peklo
ogloszenia.id=pj.id_ogloszenia

a pj.id jest polem dodatkowym

o nospor sie odedzwał jak fajnie smile.gif
trueblue
Aj, aj, wstyd.

Ale w związku z tym jest jedna kwestia. Jeśli będzie zaznaczone A i A1, to ma wybrać rekordy dokładnie z A i A1, czy A i A1 + ewentualnie inne prawa jazdy?
peklo
trueblue nie wiem czy to pytanie skierowane jest do mnie czy raczej do nospora ale wolałbym że jak wybiorę AM,A1 to żeby rzeczywiście pokazało mi te rekordy tylko z AM,A1
nospor
Cytat
Aj, aj, wstyd.
Kazdemu sie zdarza, szczegolnie po calodziennych meczarniach z takim tematem wink.gif
nospor
@peklo tylko trueblue popelnil blad na zupelnie innym poziomie niz Ty - to raz. A dwa, jak juz pisalem, po calodziennych bojach z takim tematem, kazdy moze miec chwile slabosci smile.gif
trueblue
Cytat(nospor @ 7.05.2014, 17:54:31 ) *
Kazdemu sie zdarza, szczegolnie po calodziennych meczarniach z takim tematem wink.gif

Niestety smile.gif

Kolego peklo, na razie nie mam głowy do budowy Twojego pytania, może dlatego, że nie jestem najlepszy:)
Mogę Cię naprowadzić:
  1. SELECT * FROM temat AS t,temat_tag AS tt WHERE t.id_temat=tt.id_temat AND
  2. tt.id_tag IN(1,2)
  3. AND t.id_temat NOT IN(SELECT t2.id_temat FROM temat AS t2,temat_tag AS tt2 WHERE t2.id_temat=tt2.id_temat AND tt2.id_tag IN(3,4,5,6,7,8))

Tabela temat odpowiada Twojej tabeli ogłoszeń.
Tabela temat_tag odpowiada tabeli prawo_jazdy.
Temat może mieć 0-n tagów.
W zapytaniu wybieram ogłoszenia o zadanych id tagów (np. z checkboxów), w podzapytaniu wybieram ogłoszenia z id pozostałych tagów. Dzięki temu otrzymuję ogłoszenia tylko o id_tag 1 i 2.

Nie podoba mi się to, że jest podzapytanie. Być może da się prościej.
Na dziś over!
trueblue
Masz w bazie danych tabelę słownikową z typami praw jazdy (id_prawo_jazdy,typ) czy w formularzu wyszukiwania checkbox są utworzone "na sztywno"?
Jeśli masz tabelę, to podaj schemat.
Jeśli nie masz tabeli, to podaj wszystkie możliwe id_prawo_jazdy.
peklo
o cześc , właśnie siedze i próbuję coś sklecić z twojego zapytania. Struktura pj wygląda tak

id
id_ogloszenia
id_prawo_jazdy

gdzie id_prawo_jazdy przyjmuje wartości od 1-15

Tabela główna na pole id które powiązane jest z polem id_ogloszenia w tabeli PJ

W wyszukiwarce wszystkie checkbox wpisane są na sztywno np
<input name='id_prawo_jazdy[]' type='checkbox' class='style7a' value='9'<?php if(!empty($formData['id_prawo_jazdy'])&&in_array(9,$formData['id_prawo_jazdy'])) {echo 'checked="checked"';} ?>> C+E
trueblue
Nie o tą tabelę mi chodziło, ta jest wiążąca.
O mniej więcej taką:
id_prawo_jazdy|typ
1|A
2|A1
3|B
4|C
Nie masz?
trueblue
Skoro nie masz to:
  1. <?php
  2. $bind = array(
  3. ':id_kategoria' => 1,
  4. );
  5. $where = array(
  6. 'id_kategoria = :id_kategoria'
  7. );
  8. if (!empty($_POST['szukaj']))
  9. {
  10. $_SESSION['form'] = array(
  11. 'miasto' => $_POST['miasto'],
  12. 'id_prawo_jazdy' => $_POST['id_prawo_jazdy'],
  13. );
  14. }
  15. $formData = array(
  16. 'miasto' => !isset($_SESSION['form']) ? null : $_SESSION['form']['miasto'],
  17. 'id_prawo_jazdy' => !isset($_SESSION['form']) ? null : $_SESSION['form']['id_prawo_jazdy'],
  18. );
  19.  
  20. if (!empty($formData['miasto']))
  21. {
  22. $where[] = "miasto LIKE :miasto";
  23. $bind[':miasto'] = '%' . $formData['miasto'] . '%';
  24. }
  25. $idpj_all=array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
  26. if (!empty($formData['id_prawo_jazdy']))
  27. {
  28. $where_idpj=array();
  29. $i=0;
  30. foreach($formData['id_prawo_jazdy'] as $idpj){
  31. $where_idpj[]=':id_prawo_jazdy_'.$i;
  32. $bind[':id_prawo_jazdy_'.$i++]=$idpj;
  33. $idpj_all=array_diff($idpj_all,array($idpj));
  34. }
  35. $where[] = 'id_prawo_jazdy IN('.implode(',',$where_idpj).')';
  36. }
  37.  
  38. //Przykładowe pola wyszukiwarki
  39. ?>
  40. <form action="" method="post" id="signupForm" style='display: inline'>
  41. Miasto
  42. <input type="text" id="miasto" name="miasto" value="<?php echo $formData['miasto'];?>"/>
  43.  
  44. Prawo jazdy
  45. <input name='id_prawo_jazdy[]' type='checkbox' value='1'<?php if(!empty($formData['id_prawo_jazdy'])&&in_array(1,$formData['id_prawo_jazdy'])) {echo 'checked="checked"';} ?>> AM
  46. <input name='id_prawo_jazdy[]' type='checkbox' value='2'<?php if(!empty($formData['id_prawo_jazdy'])&&in_array(2,$formData['id_prawo_jazdy'])) {echo 'checked="checked"';} ?>> A1
  47. </form>
  48.  
  49. <?php
  50. try
  51. {
  52. $stmt = $pdo->prepare("SELECT o.miasto,o.id_kategoria,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN pj p on o.id=p.id_ogloszenia WHERE ". implode( ' AND ', $where )."
  53. and o.id not in (select o2.id from ogloszenia as o2,pj as p2 where o2.id=p2.id_ogloszenia AND p2.id_prawo_jazdy in(".implode(',',$idpj_all).")) group by o.id order by o.id DESC");
  54. $stmt->execute( $bind );
  55. while($ogloszenia = $stmt -> fetch())
  56. {
  57. // WYSWIETLENIE TABELI Z DANYMI
  58. }
  59. $stmt -> closeCursor();
  60. }
  61. catch(PDOException $e)
  62. {
  63. print "Bład: " . $e->getMessage() . "<br/>";
  64.  
  65. }
  66.  
  67. ?>
trueblue
Checkbox i tak musisz mieć, tyle, że teraz generujesz je "z palca", a inaczej byłyby z tabeli.
Jeśli zrobisz tabelę, to musisz w powyższym kodzie zamienić linię 25 na zapytanie do bazy, aby otrzymać w $idpj_all tablicę nieasocjacyjną ze wszystkim id_prawo_jazdy.
trueblue
Co otrzymujesz z takiego zapytania?
  1. SELECT o.miasto,o.id_kraj,o.id_wojewodztwo,o.wyroznione,o.id,o.za,o.cena,o.id_kategoria
  2. ,o.data_dod,o.nazwa_ogloszenia,o.czas, z.id_ogloszenia,z.thumb,z.uploads,z.im,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN zdjecia z ON o.id=z.id_ogloszenia LEFT OUTER JOIN pj p ON o.id=p.id_ogloszenia WHERE aktywne=1 AND id_kategoria=1 AND id_prawo_jazdy IN(1,2)
  3. AND o.id NOT IN (SELECT o2.id FROM ogloszenia AS o2,pj AS p2 WHERE o2.id=p2.id_ogloszenia AND p2.id_prawo_jazdy IN(3,4,5,6,7,8,9,10,11,12,13,14,15))
  4. GROUP BY o.id ORDER BY o.id DESC
trueblue
Podaj wynik tego zapytania.
peklo
chodzi o to że nic się nie dzieje

$sql=" Select itd";

$stmt = $pdo->prepare($sql);
echo $sql;

i nic
trueblue
Wykonaj bezpośrednio na bazie to zapytanie i pokaż wynik.
trueblue
Teraz powinieneś otrzymać tylko 66 (nic nie wycinaj z zapytania):

  1. SELECT o.miasto,o.id_kraj,o.id_wojewodztwo,o.wyroznione,o.id,o.za,o.cena,o.id_kategoria
  2. ,o.data_dod,o.nazwa_ogloszenia,o.czas, z.id_ogloszenia,z.thumb,z.uploads,z.im,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN zdjecia z ON o.id=z.id_ogloszenia LEFT OUTER JOIN pj p ON o.id=p.id_ogloszenia WHERE id_kategoria=1 AND id_prawo_jazdy IN(1,2)
  3. AND o.id NOT IN (SELECT o2.id FROM ogloszenia AS o2,pj AS p2 WHERE o2.id=p2.id_ogloszenia AND p2.id_prawo_jazdy IN(3,4,5,6,7,8,9,10,11,12,13,14,15))
  4. GROUP BY o.id HAVING count(o.id)=2 ORDER BY o.id DESC
peklo
id_ogloszenia 66 i id_prawo_jazdy 1
trueblue
Wynik prawidłowy, a id_prawo_jazdy jest tylko jedno, bo jest grupowanie po o.id.

  1. <?php
  2. $bind = array(
  3. ':id_kategoria' => 1,
  4. );
  5. $where = array(
  6. 'id_kategoria = :id_kategoria'
  7. );
  8. if (!empty($_POST['szukaj']))
  9. {
  10. $_SESSION['form'] = array(
  11. 'miasto' => $_POST['miasto'],
  12. 'id_prawo_jazdy' => $_POST['id_prawo_jazdy'],
  13. );
  14. }
  15. $formData = array(
  16. 'miasto' => !isset($_SESSION['form']) ? null : $_SESSION['form']['miasto'],
  17. 'id_prawo_jazdy' => !isset($_SESSION['form']) ? null : $_SESSION['form']['id_prawo_jazdy'],
  18. );
  19.  
  20. if (!empty($formData['miasto']))
  21. {
  22. $where[] = "miasto LIKE :miasto";
  23. $bind[':miasto'] = '%' . $formData['miasto'] . '%';
  24. }
  25. $idpj_all=array(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15);
  26. if (!empty($formData['id_prawo_jazdy']))
  27. {
  28. $where_idpj=array();
  29. $i=0;
  30. foreach($formData['id_prawo_jazdy'] as $idpj){
  31. $where_idpj[]=':id_prawo_jazdy_'.$i;
  32. $bind[':id_prawo_jazdy_'.$i++]=$idpj;
  33. $idpj_all=array_diff($idpj_all,array($idpj));
  34. }
  35. $where[] = 'id_prawo_jazdy IN('.implode(',',$where_idpj).')';
  36. }
  37.  
  38. //Przykładowe pola wyszukiwarki
  39. ?>
  40. <form action="" method="post" id="signupForm" style='display: inline'>
  41. Miasto
  42. <input type="text" id="miasto" name="miasto" value="<?php echo $formData['miasto'];?>"/>
  43.  
  44. Prawo jazdy
  45. <input name='id_prawo_jazdy[]' type='checkbox' value='1'<?php if(!empty($formData['id_prawo_jazdy'])&&in_array(1,$formData['id_prawo_jazdy'])) {echo 'checked="checked"';} ?>> AM
  46. <input name='id_prawo_jazdy[]' type='checkbox' value='2'<?php if(!empty($formData['id_prawo_jazdy'])&&in_array(2,$formData['id_prawo_jazdy'])) {echo 'checked="checked"';} ?>> A1
  47. </form>
  48.  
  49. <?php
  50. try
  51. {
  52. $stmt = $pdo->prepare("SELECT o.miasto,o.id_kategoria,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN pj p on o.id=p.id_ogloszenia WHERE ". implode( ' AND ', $where )."
  53. and o.id not in (select o2.id from ogloszenia as o2,pj as p2 where o2.id=p2.id_ogloszenia AND p2.id_prawo_jazdy in(".implode(',',$idpj_all).")) group by o.id having count(o.id)=".count($where_idpj)." order by o.id DESC");
  54. $stmt->execute( $bind );
  55. while($ogloszenia = $stmt -> fetch())
  56. {
  57. // WYSWIETLENIE TABELI Z DANYMI
  58. }
  59. $stmt -> closeCursor();
  60. }
  61. catch(PDOException $e)
  62. {
  63. print "Bład: " . $e->getMessage() . "<br/>";
  64.  
  65. }
  66.  
  67. ?>

peklo
sad.gif
działa to w ten sposób, ze jak nic nie wybiore i wezme szukaj to nie mam nic. W ogóle nie bierze pod uwagę innych kryteriów wyszukiwania np data dodania itd (zero wyników)
Jeśli natomiast wezme zaznacze 1 i 2 to teraz wyszukuje mi rekord z tym wpisem
Chyba Cię zamęcze Trueblue smile.gif
trueblue
Zmień linie 52-53 na:
  1. $sql="SELECT o.miasto,o.id_kategoria,p.id_ogloszenia,p.id_prawo_jazdy FROM ogloszenia o LEFT OUTER JOIN pj p on o.id=p.id_ogloszenia WHERE ". implode( ' AND ', $where);
  2. if(!empty($formData['id_prawo_jazdy']))
  3. $sql.=" and o.id not in (select o2.id from ogloszenia as o2,pj as p2 where o2.id=p2.id_ogloszenia AND p2.id_prawo_jazdy in(".implode(',',$idpj_all).")) group by o.id having count(o.id)=".count($where_idpj)." order by o.id DESC";
  4. else
  5. $sql.=" group by o.id order by o.id DESC";
  6. $stmt=$pdo->prepare($sql);

peklo
ooo
jakby już dzialało dobrze. Potestuje i sie odedzwe:) Wielkie dzięki za męczarnie i pomoc smile.gif
Jak masz czas to będe mieć do Ciebie jeszcze jedną sprawę z tym zapytaniem odnośnie sortowania wyników
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.