我真的希望有人可以帮助我。我有许多产品属性类型,用户可以从中进行选择以优化在屏幕上返回给他们的产品。我想要做的是,对于每个产品属性类型,我想列出与所选类别或搜索词相关的所有属性,然后一旦他们做出选择,我仍然想要显示每个属性与类别或搜索词有关,但只有当该特定属性的产品计数大于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个连接。这需要一段时间才能执行,有更好的方法吗?表中有大约一半的产品,一旦我的网站上线,这可能是这个产品的5倍。
我真的希望我写的所有内容都有意义,如果有人可以提供帮助,我真的很感谢stackoverflow社区对此的帮助。我为这篇文章道歉;)。提前致谢
答案 0 :(得分:0)
回答你的第一个问题;是的,LEFT JOIN确实会保留初始表中的所有数据。然而,这不是问题。
您丢失空类别的原因很可能(我说这是因为我不完全了解您的数据库结构),因为where条件根据连接表中的数据过滤掉所有结果。 如果对于某个类别,所有项目都会被过滤掉(可能包括NULL连接值),您将不再从该查询中获取此类别。此外,GROUP BY是在已加入的列上完成的,这可能也会有效地消除您的其他类别。
关于第二个问题,你已经说过它需要很长时间;所以,如果你想让事情快速发挥作用,这可能不是你要走的路;)(好吧,明显的答案,低悬的果实等等)。您可能想要做的是,首先从可过滤类别中获取一组键,然后使用该数据来选择项目。
这可以防止你必须在临时表中加入你的整个产品表(至少,这就是我认为你正在做的事情),这当然需要很长时间才能获得给定数量的条目。从给定属性中选择匹配ID列表还可以提前使用索引(更多),temp-table可能没有这些索引。如果这是可能的,可行的主要取决于你的模式的结构;但我希望它可能会引导你走向你想要的方向:)