Временная таблица и левые соединения не показывают ожидаемых результатов - PullRequest
0 голосов
/ 01 марта 2012

Я действительно надеюсь, что кто-то может помочь мне с этим. У меня есть несколько типов атрибутов продукта, из которых пользователи могут выбирать продукты, которые возвращаются им на экране. Я пытаюсь сделать так, чтобы для каждого типа атрибута продукта я хотел перечислить все атрибуты, которые относятся либо к выбранной категории, либо к поисковому запросу, а затем, когда они сделали свой выбор, я все еще хочу отобразить каждый из атрибутов. которые относятся к категории или поисковому запросу, но отображают кликабельную ссылку только в том случае, если количество товаров для этого конкретного атрибута больше 1, а для тех, у которых число товаров равно нулю, я хочу перечислить их, но сделать их не кликабельными. Пример того, чего я пытаюсь достичь, можно найти на веб-сайте ASOS в меню слева. http://www.asos.com/Women/Dresses/Cat/pgecategory.aspx?cid=8799#state=Rf961%3D3340%2C3341%40Rf-200%3D20&parentID=Rf-300&pge=0&pgeSize=20&sort=-1

Первоначально я пытался использовать просто соединения для достижения этой цели, но я не смог сделать это успешно. Поэтому я решил создать временную таблицу для каждого типа атрибута, в которой содержался список всех атрибутов, связанных с основным запросом, а затем был создан уточненный запрос с левым объединением. Вот мой код:

CREATE TEMPORARY TABLE temp_table 
    SELECT su_types.id, type AS item FROM su_types 
    INNER JOIN su_typerefs ON su_types.id=su_typerefs.id 
    INNER JOIN su_pref ON su_typerefs.mykey = su_pref.mykey 
WHERE wp_category_id =40 GROUP BY su_typerefs.id

$sudb->query($query);

if ($sudb->affected_rows > 0) {     

SELECT temp_table.id,item,COUNT(su_typerefs.mykey) AS product_count FROM temp_table 
    LEFT JOIN su_typerefs ON temp_table.id=su_typerefs.id 
    LEFT JOIN su_pref ON su_typerefs.mykey = su_pref.mykey 
    LEFT JOIN su_stylerefs ON su_pref.mykey = su_stylerefs.mykey 
    LEFT JOIN su_productrefs ON su_pref.mykey = su_productrefs.mykey
WHERE wp_category_id =40 AND su_stylerefs.id in (91) AND su_productrefs.id in (54) AND su_typerefs.id in (159) GROUP BY su_typerefs.id

if ($itemresults = $sudb->query($query)) {

    while($itemresult = $itemresults->fetch_array(MYSQLI_ASSOC)) {
    $id=$itemresult['id'];
    $item=$itemresult['item'];
    $product_count=$itemresult['product_count'];


        build_link($list_type, $item, $product_count, $id);
    }
}

В приведенном выше примере первый запрос выбирает все типы товаров, которые относятся к определенной категории, например платья. И второй запрос основан на уточнениях, внесенных пользователем в категорию, в данном примере это продукт, тип продукта и стиль. Пользователь также может уточнить свой поиск по цвету, подгонке, ткани и дизайну.

Есть несколько проблем с этим:

1) Количество результатов, возвращаемых во втором запросе, не совпадает с результатами первого запроса. Используя приведенное выше в качестве примера, я хочу перечислить все продукты, которые относятся к выбранной категории, а затем, используя второй запрос, вернуть количество продуктов для каждого из этих продуктов, как я описал выше. Так что, если временный стол вернется, брюки, джинсы и юбки. Я ожидал, что эти три элемента будут отображаться на экране в зависимости от условий, применяемых во втором запросе, однако мои результаты могут показывать только брюки и джинсы, если во втором запросе нет совпадения для юбок. Я думал, что использование левого соединения будет означать, что будут отображены все результаты временной таблицы.

2) Также мне интересно, делаю ли я это наиболее эффективным способом. У меня есть в общей сложности 8 групп атрибутов, и, следовательно, нужно сделать выше 8 раз. Если пользователь решает уточнить результаты, используя все 8 групп атрибутов, то в дополнение к временному соединению таблицы будет всего 9 соединений для каждого типа. Выполнение занимает некоторое время, есть ли лучший способ сделать это? В таблице приблизительно 1/2 миллиона товаров, и это, вероятно, будет в 5 раз больше, если мой сайт заработает.

Я действительно надеюсь, что все, что я написал, имеет смысл, и я очень признателен за помощь сообщества stackoverflow, если кто-нибудь сможет помочь. Извиняюсь за сочинение;). Заранее спасибо

1 Ответ

0 голосов
/ 01 марта 2012

ответить на ваш первый вопрос;да, LEFT JOIN действительно сохранит все данные из исходной таблицы.Это, однако, не проблема.

Причина, по которой вы теряете пустые категории, наиболее вероятна (я говорю это, потому что я не полностью знаю вашу структуру БД), потому что условие where отфильтровываетрезультаты на основе данных в объединенных таблицах.Если для категории все элементы отфильтрованы (возможно, включая объединенные значения NULL), вы больше не получите эту категорию из этого запроса.Также GROUP BY выполняется для объединенного столбца, который также может эффективно уничтожить другие ваши категории.

Что касается второго вопроса, вы уже заявляете, что он занимает много времени;так что это, вероятно, не тот путь, если вы хотите, чтобы все работало быстро;) (хорошо, очевидный ответ, низко висящие фрукты и т. д.).Возможно, вы захотите сначала получить набор ключей из фильтруемых категорий и использовать эти данные для выбора элементов.

Это предотвращает необходимость объединения всей таблицы продуктов во временной таблице (по крайней мере, это то, что я думаю, вы делаете), что, конечно, займет много времени с заданным количеством записей.Выбор списка совпадающих идентификаторов из заданных атрибутов также дает вам преимущество в использовании ваших индексов (больше), чего, вероятно, не будет у временной таблицы.Если это возможно и выполнимо, зависит главным образом от структуры вашей схемы;но я надеюсь, что это может привести вас в том направлении, в котором вы хотите идти:)

...