ďťż
 
Problem z zaptytaniem SQL ďťż
 
Problem z zaptytaniem SQL
Zobacz wiadomości
 
Cytat
A gdyby tak się wedrzeć na umysłów górę, / Gdyby stanąć na ludzkich myśli piramidzie, / I przebić czołem przesądów chmurę, / I być najwyższą myślą wcieloną. . . Juliusz Słowacki, Kordian
Indeks BCB i MySQL subiekt gt fototapeta
 
  Witamy

Problem z zaptytaniem SQL



Marek - 13-11-2006 00:43
Problem z zaptytaniem SQL
  Witam,

Wykonałem w HTMLu formularz wyszukiwania produktów. Są w nim checkboxy
określające pewne cechy tych produktów. Chciałbym wyłonić z bazy produktów,
te które łącznie spełniają zaznaczone cechy. Chyba jest zbyt późno bo nie
wiem jak to zrobić w przypadku gdy struktura jest jak poniżej (w
uproszczeniu):

create table produkt
(
produkt_id primary key,
....
);

create table lista_wszystkich_mozliwych_cech
(
lista_wszystkich_mozliwych_cech_id primary_key,
nazwa_cechy text,
....
);

create table cecha
(
cecha_id primary key,
lista_wszystkich_mozliwych_cech_id foreign key
lista_wszystkich_mozliwych_cech(lista_wszystkich_m ozliwych_cech_id),
produkt_id foreign key references produkt (produkt_id),
wartosc_cechy text
);

Generalnie jeśli jakaś cecha występuje w danym produkcie to w tabeli cech
powstaje rekord powiącany z danym produktem i z nazwą tejże cechy. Produkt w
ten sposób może posiadać zmienną ilość cech. Z formularza HTML odrzymuję
listę wartości lista_wszystkich_mozliwych_cech_id, które zostały "kliknięte"
w parametrach wyszukiwarki. No i nie mam koncepcji co dalej ...

--
Pozdrawiam,
Marek





Marek - 13-11-2006 00:43

  Uzupełnienie.

Być może to co wczoraj napisałem nie jest jasne a do tego narobiłem ze
zmęczenia błędów. Dlatego dorzucę przykład obrazujący zachowanie się tej
struktury danych i to co chcę osiągnąć. Załóżmy, że mamy dwa produkty:
telefon komórkowy oraz używane kapcie. Załóżmy, że mamy dostępne następujące
cechy produktów: GPRS, kolor oraz aromat. Przypisujemy telefonowi cechę GPRS
i kolor a kapciom: kolor i aromat. W efekcie w tabeli "cecha" mamy 4 rekrdy:
dwa związane z telefonem i dwa z kapciami. Jeśli uzytkownik w wyszukiwarce
zaznaczy opcję "kolor" to pytanie SQL powinno zwrócić oba produkty. Jeśli
dodatkowo zostanie zaznaczone pole "aromat" to tym razem powinien być
zwrócony jedynie 1 rekord: kapie.




Mitis - 13-11-2006 00:43

  Aaye Marek,

> Uzupełnienie.
>
> Być może to co wczoraj napisałem nie jest jasne a do tego narobiłem ze
> zmęczenia błędów. Dlatego dorzucę przykład obrazujący zachowanie się
> tej struktury danych i to co chcę osiągnąć. Załóżmy, że mamy dwa
> produkty: telefon komórkowy oraz używane kapcie. Załóżmy, że mamy
> dostępne następujące cechy produktów: GPRS, kolor oraz aromat.
> Przypisujemy telefonowi cechę GPRS i kolor a kapciom: kolor i aromat.
> W efekcie w tabeli "cecha" mamy 4 rekrdy: dwa związane z telefonem i
> dwa z kapciami. Jeśli uzytkownik w wyszukiwarce zaznaczy opcję "kolor"
> to pytanie SQL powinno zwrócić oba produkty. Jeśli dodatkowo zostanie
> zaznaczone pole "aromat" to tym razem powinien być zwrócony jedynie 1
> rekord: kapie.
>

jeden parametr
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;

dwa parametry
SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1 AND t2.column3=3

nie pamietam teraz dokladnie, ale chyba kolejnosc warunkow po WHERE jest
obojetna




Adam Płaszczyca - 13-11-2006 00:43

  On Wed, 11 Oct 2006 10:03:35 +0200, "Marek"
<marek1967@spam.interia.pl> wrote:

>dwa związane z telefonem i dwa z kapciami. Jeśli uzytkownik w wyszukiwarce
>zaznaczy opcję "kolor" to pytanie SQL powinno zwrócić oba produkty. Jeśli
>dodatkowo zostanie zaznaczone pole "aromat" to tym razem powinien być
>zwrócony jedynie 1 rekord: kapie.

Tutaj trzeba użyć dynamicznego SQL-a, bo zmieniasz ilośc parametrów,
albo też obsłużyć całą rzecz programowo.

Tak na szybko można zrobić to tak:
Dla jednej cechy:

SELECT distinct produkt_id from
cecha AS C1
where
C1.lista_wszystkich_mozliwych_cech_id=<cecha_jaka_ nas_interesuje_1>

Dla dwóch robimy tak:
SELECT distinct produkt_id from
cecha AS C1
JOIN
cecha AS C2
ON C1.produkt_id=C2.produkt_id
where
C1.lista_wszystkich_mozliwych_cech_id=<cecha_jaka_ nas_interesuje_1>
AND
C2.lista_wszystkich_mozliwych_cech_id=<cecha_jaka_ nas_interesuje_2>

Dla trzech tak:
SELECT distinct produkt_id from
cecha AS C1
JOIN
cecha AS C2
ON C1.produkt_id=C2.produkt_id
JOIN
cecha AS C3
ON C1.produkt_id=C3.produkt_id
where
C1.lista_wszystkich_mozliwych_cech_id=<cecha_jaka_ nas_interesuje_1>
AND
C2.lista_wszystkich_mozliwych_cech_id=<cecha_jaka_ nas_interesuje_2>
AND
C2.lista_wszystkich_mozliwych_cech_id=<cecha_jaka_ nas_interesuje_3>

I tak dalej.

--
___________ (R)
/_ _______ Adam 'Trzypion' Płaszczyca (+48 502) 122 688
___/ /_ ___ ul. Na Szaniec 23/70, 31-560 Kraków
_______/ /_ http://trzypion.oldfield.org.pl/fotki/Ponidzie_2006/
___________/ mail: _555@irc.pl GG: 3524356





Marek - 13-11-2006 00:43

  > jeden parametr
> SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1;
>
> dwa parametry
> SELECT * FROM t1, t2 WHERE t2.column2=5 AND t1.column1=t2.column1 AND
> t2.column3=3
>
> nie pamietam teraz dokladnie, ale chyba kolejnosc warunkow po WHERE jest
> obojetna

Witaj,

Nie bardzo załapałem Twoje intencje. To co nazwałeś column1, column2 i
column3 to jest ta sama kolumna u mnie nazwana
lista_wszystkich_mozliwych_cech_id. W takim razie jeśli szukamy rekordu,
który ma jednocześnie wartość pola ustawioną na 2 i 3 to z pewnością nie
znajdziemy go.




Marek - 13-11-2006 00:43

  Hmmm ... troszkę to zawiłe. Oczywiście mogę dynamicznie budować SQL i to
właśnie robię. Boję się tylko, że przy takim rozwiązaniu kliknięcie np. 50
opcji zatka mi serwer obliczeniami. W międzyczasie obszedłem ten problem
poniższą strukturą (PHP) lecz nadal nie wiem czy to nie jest tylko
obejściem:

SELECT * FROM product, ...inne relacje WHERE ... AND product_id IN
(SELECT product_id FROM cecha
WHERE lista_wszystkich_mozliwych_cech_id IN (".join(",",$array).")
GROUP BY product_id
HAVING count(product_id)=".count($array).")";

Zmienna $array zawiera kliknięte przez usera checkboxy. Jest to lista ID
zaznaczonych cech. Jeśli ktoś zaznaczył np. 10 cech to szukam wszystkich
produktów należących do jakiejkolwiek z tych cech. Jeśli znalezionych
produktów o danym ID jest dokładnie tyle ile kliknięto cech to znaczy, że
dany produkt posiada wszystkie te cechy, a więc spełnia kryterium
wyszukiwania. To działa lecz nie lubię konstrukcji z IN gdyż są nieefektywne
ponoć. Engine musi wybrać wszystkie rekordy po lewej i po prawej stronie IN
i potem porównuje wyniki. Dlatego oczekuję jeszcze innego rozwiązania, o ile
istnieje.




Paweł Matejski - 13-11-2006 00:43

  Marek wrote:
> Hmmm ... troszkę to zawiłe. Oczywiście mogę dynamicznie budować SQL i to
> właśnie robię. Boję się tylko, że przy takim rozwiązaniu kliknięcie np.
> 50 opcji zatka mi serwer obliczeniami. W międzyczasie obszedłem ten
> problem poniższą strukturą (PHP) lecz nadal nie wiem czy to nie jest
> tylko obejściem:
>
>
> SELECT * FROM product, ...inne relacje WHERE ... AND product_id IN
> (SELECT product_id FROM cecha
> WHERE lista_wszystkich_mozliwych_cech_id IN (".join(",",$array).")
> GROUP BY product_id
> HAVING count(product_id)=".count($array).")";
>
> Zmienna $array zawiera kliknięte przez usera checkboxy. Jest to lista ID
> zaznaczonych cech. Jeśli ktoś zaznaczył np. 10 cech to szukam wszystkich
> produktów należących do jakiejkolwiek z tych cech. Jeśli znalezionych
> produktów o danym ID jest dokładnie tyle ile kliknięto cech to znaczy,
> że dany produkt posiada wszystkie te cechy, a więc spełnia kryterium
> wyszukiwania. To działa lecz nie lubię konstrukcji z IN gdyż są
> nieefektywne ponoć. Engine musi wybrać wszystkie rekordy po lewej i po
> prawej stronie IN i potem porównuje wyniki. Dlatego oczekuję jeszcze
> innego rozwiązania, o ile istnieje.

Heh... podobno, gdzieś napisali... Pamiętaj, jeśli nie znasz źródła, albo
wytłumaczenia dlaczego tak się dziej, nie jesteś w stanie zweryfikować takiej
informacji. A to nie jest prawdą przynajmniej dla kilku baz.
Ja rozumiem, żeby Ci to zapytanie działało wolno, albo miał z nim inne z nim
problemy. Ale tak z góry założyć, że jest złe...

--
P.M.




Marek - 13-11-2006 00:43

  > Heh... podobno, gdzieś napisali... Pamiętaj, jeśli nie znasz źródła, albo
> wytłumaczenia dlaczego tak się dziej, nie jesteś w stanie zweryfikować
> takiej
> informacji. A to nie jest prawdą przynajmniej dla kilku baz.
> Ja rozumiem, żeby Ci to zapytanie działało wolno, albo miał z nim inne z
> nim
> problemy. Ale tak z góry założyć, że jest złe...

No dobrze, to pozostaje mi niczego nie zmieniać :-) Dzięki za zaangażowanie.




elessar - 13-11-2006 00:43

  Marek napisał(a):
> Hmmm ... troszkę to zawiłe. Oczywiście mogę dynamicznie budować SQL i to
> właśnie robię. Boję się tylko, że przy takim rozwiązaniu kliknięcie np.
> 50 opcji zatka mi serwer obliczeniami. W międzyczasie obszedłem ten
> problem poniższą strukturą (PHP) lecz nadal nie wiem czy to nie jest
> tylko obejściem:
>
>
> SELECT * FROM product, ...inne relacje WHERE ... AND product_id IN
> (SELECT product_id FROM cecha
> WHERE lista_wszystkich_mozliwych_cech_id IN (".join(",",$array).")
> GROUP BY product_id
> HAVING count(product_id)=".count($array).")";
>
> Zmienna $array zawiera kliknięte przez usera checkboxy. Jest to lista ID
> zaznaczonych cech. Jeśli ktoś zaznaczył np. 10 cech to szukam wszystkich
> produktów należących do jakiejkolwiek z tych cech. Jeśli znalezionych
> produktów o danym ID jest dokładnie tyle ile kliknięto cech to znaczy,
> że dany produkt posiada wszystkie te cechy, a więc spełnia kryterium
> wyszukiwania. To działa lecz nie lubię konstrukcji z IN gdyż są
> nieefektywne ponoć. Engine musi wybrać wszystkie rekordy po lewej i po
> prawej stronie IN i potem porównuje wyniki. Dlatego oczekuję jeszcze
> innego rozwiązania, o ile istnieje.

heh widze ze wykorzystales moje zapytanie :-) Co do IN to jest tak samo
nieefektywne jak lista_wszystkich_mozliwych_cech_id = 1 or
lista_wszystkich_mozliwych_cech_id = 2 ...
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • effulla.pev.pl
  • comp
    jak to =?ISO-8859-2?Q?zrobi=E6=2E=2E=2E=3F_TSQL_sql_server?==?ISO-8859-2?Q?_?= [MSSQL2000] Problem z =?ISO-8859-2?Q?tabel=B1/indeksem/zapytanie?==?ISO-8859-2?Q?m_czy_b=B3=B1d_w_bazie_danych=2E=2E=2E?= Jak =?windows-1250?Q?pobra=E6_szacowan=B9_wielko=9C=E6_zbiory_wy nikowego_w_MS?==?windows-1250?Q?_SQL_2005=3F?= =?iso-8859-2?Q?=5BMS_SQL=5D_Czy_mo=BFna_wywo=B3a=E6_funkcje_t ylko_raz_dla?==?iso-8859-2?Q?_ca=B3ego_zbioru_=BCr=F3d=B3owego=3F?= [MSSQL] =?ISO-8859-2?Q?zgodno=B6ci_z_licencjami_Microsoft_?==?ISO-8859-2?Q?SQL_Server?= =?ISO-8859-2?Q?k=B3opot_z_uruchomieniem_MY_SQL_dla_C?==?ISO-8859-2?Q?MS_i_CRM_na_Fedora_Core_3?= Oracle PL/SQL Wstawianie =?ISO-8859-2?Q?wynik=F3w_kolekcji_d?==?ISO-8859-2?Q?o_tabeli?= [MSSQL] ACCESS - SQL =?ISO-8859-2?Q?B=B3ad_w_konwersji_lic?==?ISO-8859-2?Q?zb?= =?iso-8859-2?Q?=5Bmssql=5D_Zapytania_rekurencyjne__-_czy_sk=B3adnia_sql?==?iso-8859-2?Q?_co=B6_takiego_przewiduje_=3F?= [Oracle PL/SQL] Cursor i zapis =?ISO-8859-2?Q?rekord=F3w_do_?==?ISO-8859-2?Q?kolejnych_plik=F3w?=
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • wawa19wwa91.pev.pl
  • Cytat

    Decede mihi sole - nie zasłaniaj mi słonca.
    Gdy kogoś kochasz, jesteś jak stworzyciel świata - na cokolwiek spojrzysz, nabiera to kształtu, wypełnia się barwą, światłem. Powietrze przytula się do ciebie, choćby był mróz, a ty masz w sobie tyle radości, że musisz ją rozdawać wokoło, bo się w tobie nie mieści
    Hoc fac - tak czyń.
    A tergo - od tyłu; z tyłu.
    I czarne włosy posiwieją. Safona

    Valid HTML 4.01 Transitional

    Free website template provided by freeweblooks.com