Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: Wyszukiwarka z polami dodawanymi przez administratora
Forum PHP.pl > Forum > Bazy danych > MySQL
Neider
Witam

Na stronie której piszę umożliwiłem administratorowi, dodawanie atrybutów produktu. Posiadam 3 tabele. Produkt, Atrybuty, ProduktAtrybuty. Problem pojawia się przy wyszukiwaniu w/g tych "dynamicznych" pól. Zakładam że może byc dowolna liczba pól w.g których można szukać.

Tabela produktów:
- id
- inne pola opisujące produkt

Tabela atrybuty:
- id
- nazwa
- typ

tabela ProduktyAtrybuty:
- id
- produkt_id
- atrybut_id
- wartosc

Przykładowe dane w ProduktyAtrybuty:
ID | produkt_id | atrybut_id | wartosc
1 | 1 | 1 | 1
2 | 1 | 2 | 1
3 | 2 | 1 | 2
4 | 2 | 2 | 1

Teraz załóżmy że użytkownik chce wyszukać poprzez formularz, produkt który miałby atrybut_id 1 o wartości 1 oraz atrybut_id 2 również o wartości 1.
Próbowałem wielu zapytań jednak nic co by działało przy jednym zapytaniu mi nie udało się napisać:

SELECT p.produkt_id FROM produktyatrybuty p WHERE (p.atrybut_id = 1 AND p.wartosc = 1) OR (p.atrybut_id = 2 AND p.wartosc = 1)

Dla każdego kolejnego atrybutu, jeżeli uczestniczyłby w wyszukiwaniu dodawałbym kolejną parę OR (p.atrybut_id = id AND p.wartosc = wartosc).
To zapytanie daje mi praktycznie ile razy dany produkt występuje w atrybutach i jeżeli ilośc wystapień = ilości atrybutów w/g których wyszukuje, wtedy zapisuje ID i następnie wyszukuje juz produkty w ID w tablicy. Rozwiązanie to uważam za beznadziejne, jednak nic lepszego mi nie wpadło do głowy na razie. Ktoś miał może z czymś podobym do czynienia? Mógłby mnie ktoś nakierować, czy da się to załatwić jakoś jednym zapytaniem wyciągającym od razu produkty?
dmateo
Cytat(Neider @ 8.09.2011, 19:22:20 ) *
  1. SELECT p.produkt_id FROM produktyatrybuty p WHERE (p.atrybut_id = 1 AND p.wartosc = 1) OR (p.atrybut_id = 2 AND p.wartosc = 1)


To zapytanie wybierze produkty, które np. mają atrybut_id = 2 i wartosc = 1, ale dla atrybut_id = 1 moze miec wartosc = 123 i takze sie zalapie. W tej chwili nie widze rozwiazan z jednym zapytaniem. Z kilkoma mozna zrobic tak:

1. Najpierw sciagnac produkty z atrybut_id = 1 i wartosc = 1. W kolejnym zapytanie sciagnac atrybut_id = 2 i wartosc = 1 i sprawdzic ktore pojawily sie w obu wynikach (to pochlonie dosyc duzo zasobow)

2. Ewentualnie procedura w bazie
luck
Strzał w ciemno, bo nie jestem pewny czy dobrze Cię rozumiem. W dodatku pisane na kolanie, ale może mniej więcej o to chodzi?
  1. SELECT prod.* FROM produkty prod WHERE prod.id IN(SELECT p.produkt_id FROM produktyatrybuty p WHERE (p.atrybut_id = 1 AND p.wartosc = 1) AND (p.atrybut_id = 2 AND p.wartosc = 1))

Neider
@dmateo: Też myślałem o procedurze, przynajmniej wszystko po stronie bazy by się wykonało

@luck: No dokładnie o cos takiego chodzi, z tym że to zapytanie zawsze zwróci pusty wynik. Bo nie ma jednocześnie takiego rekordu gdzie atrybut_id = 1 i atrybut_id = 2 wink.gif Najgorszy właśnie jest ten łącznik między parami id,wartość, gdyby tam mogło być OR to nie było by problemu, ale przy wyszukiwaniu atrybuty produktu muszą spełniać wszystkie założone kryteria, a nie tylko jedno z nich.
luck
Sorki, oczywiście masz rację wink.gif Nie wiem jak będzie z wydajnością dla większej liczby atrybutów, ale może na coś Cię to naprowadzi:
  1. SELECT p.* FROM produktyatrybuty pa1
  2. RIGHT JOIN produktyatrybuty pa2 ON pa2.`produkt_id` = pa1.`produkt_id`
  3. AND pa2.atrybut_id = 2 AND pa2.`wartosc` = 2
  4. LEFT JOIN produkty p ON p.id = pa2.produkt_id
  5. WHERE (pa1.`atrybut_id` = 1 AND pa1.`wartosc` = 1)
Neider
Ok sprawdze to jutro w pracy, dam znać jak się uda.

Zapytanie działa w 100% tak jak chciałem. Wielkie dzięki, co do wydajności to pewnie ograniczę, żeby w podstawowej wyszukiwarce używać max 4-5 atrybutó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.