Próbuję napisać stronę z produktami na podstawie kryteriów od użytkownika. Poniższe pola są przekazywane domyślnie:MySQL Powracanie wierszy na podstawie dodatkowych parametrów PDO
- QString (aby dopasować nazwę produktu/opis)
- maxPrice/minPrice (zrobić od cen w tabeli)
- minDate/MaxDate (aby szukać produkty między terminami dostępność)
Powyższe daje mi wartości zwracane.
Kolejna para pola są opcjonalne i dodał poprzez jQuery na podstawie kategorii:
- Kategoria: category_id który pasuje powrotem do deals.deals_category_id (ten nadal działa)
Based w kategorii mogą pojawiać się dodatkowe atrybuty (takie jak umowy z dostawcami usług, producent), które będą dynamicznie widoczne w interfejsie użytkownika. Od tego momentu klient może za pomocą pól wyboru wybrać producentów, którymi są zainteresowani i dostawcę usług.
Moi Tabele zawierają:
- oferty (zawiera produkty z deal_category_id)
- Kategorie (Wszystkie oferty są połączone z kategorii)
- Category_attributes (dodatkowe atrybuty na kategorie Jeśli produkt jest. załadowane do kategorii będą również dostarczane z dodatkowymi selektorami atrybutów
- Deal_attribute_options (Zawiera relacje powiązane opcje w oparciu o atrybut (gdzie atrybutem mogą być usługodawcy i atrybut opti mogą mieć AT & T, t-Mobile itp.).
- Deal_attribute_values (Zawiera wartości wybranych opcji atrybutów podczas tworzenia produktu Powiedzmy, że utworzyłem nowy telefon komórkowy i wybrałem kategorię telefony komórkowe, produkt będzie musiał podać wartości dla opcji atrybut_. Będą one otrzymywać listę np. sieci komórkowe lub producenci i powiązać producenta produktu z tym konkretnym producentem ..
Do tej pory posiadam w bazie danych kilka produktów, z których każdy jest powiązany z kategorią i na podstawie atrybutów powiązanych z tą kategorią. kategoria, każdy produkt wybrałby wartość dla każdej opcji atrybutu.Jeżeli istniałyby 2 atrybuty (producent, sieć komórkowa), każdy produkt miałby wartość w deal_valename_values łączącą dealeid, attribute_id i th en wybraną wartość (aby produkty mogły być producentem Samsunga, a Vodafone jako usługodawcą).
Co teraz próbuję zrobić, opiera się na kwerendzie wyszukiwania, zwróć powiązane wiersze na podstawie filtrowania z przodu. Po zmianie formy na interfejsie, nastąpi przekształcenie do postaci szeregowej wartości i za pomocą ajax'a zwrócimy prawidłowe produkty na podstawie tych zapytań.
Dostaję go do pracy doskonale, z wyjątkiem wartości atrybut_wartości. Podejrzewam, że ma to coś wspólnego z moją klauzulą IN() w zapytaniu, ale mam nadzieję, że ktoś może mi pomóc tutaj z tym, co robię źle.
Oto metoda model:
public function getDeals() {
$select = array();
$tables = array();
$where = array();
$values = array();
// Default to get all deal rows:
$select[] = "`deals`.*";
$tables[] = "`deals`";
// Get the category Name AND ID
$select[] = "`deal_categories`.`name` AS `catName`";
$tables[] = "`deal_categories`";
$where[] = "`deals`.`deal_category_id`=`deal_categories`.`id`";
// Look if a category was selected:
$cat = $_POST['category'];
if ($cat != "") {
$where[] = "`deals`.`deal_category_id`=?";
$values[] = $cat;
}
// Assign a query of the deal by string:
if ($_POST['searchDeals'] != "") {
$where[] = "CONCAT_WS(' ',`deals`.`name`,`deals`.`description`) LIKE ?";
$values[] = "%" . str_replace(" ", "%", htmlspecialchars($_POST['searchDeals'])) . "%";
}
// Process Min/Max PRicing:
if (isset($_POST['minPrice'])) {
$minPrice = intval($_POST['minPrice']);
$where[] = "`deals`.`price` >= ?";
$values[] = $minPrice;
}
if (isset($_POST['maxPrice'])) {
$maxPrice = intval($_POST['maxPrice']);
$where[] = "`deals`.`price` <= ?";
$values[] = $maxPrice;
}
// PRocess the min/max dates:
if (isset($_POST['minDate'])) {
$minDate = $_POST['minDate'];
$where[] = "`deals`.`start_date` >= ?";
$values[] = $minDate;
}
if (isset($_POST['maxDate'])) {
$maxDate = $_POST['maxDate'];
$where[] = "`deals`.`end_date` <= ?";
$values[] = $maxDate;
}
if (isset($_POST['attr']) && valid_array($_POST['attr'])) {
$tables[] = "`deal_attribute_values`";
foreach ($_POST['attr'] AS $attrID => $checked) {
$values[] = $attrID;
$where_condition = "`deals`.`id`=`deal_attribute_values`.`deal_id`
AND `deal_attribute_values`.`deal_attribute_id`=?
AND `deal_attribute_values`.`value` IN (";
$bind_placeholder = array();
foreach ($checked as $val) {
$bind_placeholder[] = "?";
$values[] = $val;
}
$where_condition .= implode(',', $bind_placeholder) . ")";
$where[] = $where_condition;
}
}
$sql = "SELECT " . implode(", ", $select) . " FROM " . implode(",", $tables) . " WHERE " . implode(" AND ", $where);
return $this->get($sql, $values);
}
Oto próbka POST tym atrybutów (zauważ, że kluczem 3 i 4) reprezentuje zbiór atrybutów (producent i dostawca usług). Wartości dla nich to sprawdzone opcje, przez które chcemy działać IN().
Array
(
[searchDeals] =>
[category] => 2
[attr] => Array
(
[3] => Array
(
[0] => 8
[1] => 9
[2] => 12
[3] => 10
)
[4] => Array
(
[0] => 4
[1] => 7
[2] => 5
)
)
[minPrice] => 100000
[maxPrice] => 9500
[minDate] => 2014-10-26 00:00:00
[maxDate] => 2014-11-30 00:00:00
)
Tutaj jest wyprowadzany SQL w oparciu o wyżej (aktualizowane na podstawie aktualizacji kodu):
SELECT `deals`.*, `deal_categories`.`name` AS `catName` FROM `deals`,`deal_categories`,`deal_attribute_values` WHERE `deals`.`deal_category_id`=`deal_categories`.`id` AND `deals`.`deal_category_id`=? AND `deals`.`price` >= ? AND `deals`.`price` <= ? AND `deals`.`start_date` >= ? AND `deals`.`end_date` <= ? AND `deals`.`id`=`deal_attribute_values`.`deal_id` AND `deal_attribute_values`.`deal_attribute_id`=? AND `deal_attribute_values`.`value` IN (?,?,?,?) AND `deals`.`id`=`deal_attribute_values`.`deal_id` AND `deal_attribute_values`.`deal_attribute_id`=? AND `deal_attribute_values`.`value` IN (?,?,?)
A oto wartości PDO:
Array
(
[0] => 2
[1] => 100000
[2] => 9500
[3] => 2014-10-26 00:00:00
[4] => 2014-11-30 00:00:00
[5] => 3
[6] => 8
[7] => 9
[8] => 12
[9] => 10
[10] => 4
[11] => 4
[12] => 7
[13] => 5
)
Mogę potwierdzić, że otrzymuję wyniki do momentu wprowadzenia atrybutów. Nadal mogę uzyskać wynik, jeśli odznaczam wszystkie atrybuty (zarówno dla producenta, jak i usługodawcy) i wybieram tylko 1 atrybut np. "Apple", który następnie zwraca pojedynczy produkt, ale jeśli wybiorę powiązanego dostawcę usług, nie ma wyniki.
Zasadniczo z atrybutami chcę wybrać wiersz, jeśli wartość tego produktu w tabeli wartości atrybutów mieści się w atrybutach w klauzuli IN(). Ponieważ będzie wiele atrybutów opartych na kategorii i wiele produktów powinno zostać zwróconych, jeśli utrzymam Apple, Samsung i Vodacom/MTN jako SP. Jeśli produkt jest samsung i Vodacom/MTN powinien powrócić lub jeśli nie wybrano producenta, a my wybieramy Vodacom/MTN tylko jako SP, powinien on zwracać wszystkie telefony, które są albo MTN/Vodacom. Nawet jeśli nie ma Vodacom, powinien przynajmniej zwrócić wszystkie MTN.
Proszę dać mi znać, jeśli potrzebujesz dodatkowej pomocy/informacji. Starałem się mieć jak najwięcej szczegółów tutaj więc nadzieję, że każdy rozumie :)
** ODPOWIEDŹ UPDATE **
Zrobiłem 2 zmiany kodu wysłana przez Alex, który działa na mojej stronie! Dziękuję Alex :)
if (isset($_POST['attr']) && valid_array($_POST['attr'])) {
foreach ($_POST['attr'] AS $attrID => $checked) {
$current_table = "`deal_attribute_values` AS `dav" . $attrID."`";
$asName = "`dav".$attrID."`";
$values[] = $attrID;
$where_condition = "`deals`.`id`=".$asName.".`deal_id`
AND " . $asName . ".`deal_attribute_id`=?
AND " . $asName . ".`value` IN (";
$bind_placeholder = array();
foreach ($checked as $val) {
$bind_placeholder[] = "?";
$values[] = $val;
}
$where_condition .= implode(',', $bind_placeholder) . ")";
$where[] = $where_condition;
$tables[] = $current_table;
}
}
1 wszystkich, bardzo szczegółowe pytania. +1 za to. – itachi