这是MySQL和PHP创建SQL查询,订单结果通过何种条件下它们满足
我有一个包含以下各列的表格:
navigation_id (unsigned int primary key)
navigation_category (unsigned int)
navigation_path (varchar (256))
navigation_is_active (bool)
navigation_store_id (unsigned int index)
数据将被填充,如:
1, 32, "4/32/", 1, 32
2, 33, "4/32/33/", 1, 32
3, 34, "4/32/33/34/", 1, 32
4, 35, "4/32/33/35/", 1, 32
5, 36, "4/32/33/36/", 1, 32
6, 37, "4/37/", 1, 32
... another group that is under the "4/37" node
... and so on
所以这将代表一棵树状结构。我的目标是编写一个SQL查询,给定商店ID为32,类别ID为33,将返回
首先,作为类别33的父项的一组元素(在本例中为4和32)
然后,一组是33类别的子元素(在此情况下34,35,和36)
接着的下4类的“根”类别中的其余(在这种情况下37) 。
所以下面的查询将返回正确的结果:
SELECT * FROM navigation
WHERE navigation_store_id = 32
AND (navigation_category IN (4, 32)
OR navigation_path LIKE "4/32/33/%/"
OR (navigation_path LIKE "4/%/"
AND navigation_category <> 32))
我的问题是,我想订购类别的“组”,在上述的33首,33秒的儿童(父母列出的顺序,以及根节点的父代最后)。因此,如果他们符合第一个条件,则先排序,如果他们符合第二个条件,则排序第二个条件,如果他们符合第三个(和第四个)条件,则排列第二个条件。
你可以看到的品类结构是如何工作的,在这个网站的例子:
www.eanacortes.net
你可能会注意到,这是相当缓慢的。目前我这样做的方式是使用magento的原始类别表并在其上执行三个特别慢的查询;然后将结果放在一起。使用这张新表格,我正在解决另一个与magento有关的问题,但同时也想提高我的表现。我看到这一切的最佳方式是将所有三个查询放在一起,并通过让结果正确排序来减少PHP的工作量。
感谢
编辑
好了,现在它的伟大工程。将其从4秒降至500毫秒。现在大提速:)
这是我在Colleciton类代码:
// get our data
$navigation = Mage::getModel("navigation/navigation")->getCollection();
$navigation->
addStoreFilter(Mage::app()->getStore()->getId())->
addCategoryFilter($currentCat);
// put it in an array
$node = &$tree;
$navArray = array();
foreach ($navigation as $cat)
{
$navArray[] = $cat;
}
$navCount = count($navArray);
$i = 0;
// skip passed the root category
for (; $i < $navCount; $i++)
{
if ($navArray[$i]->getNavigationCategory() == $root)
{
$i++;
break;
}
}
// add the parents of the current category
for (; $i < $navCount; $i++)
{
$cat = $navArray[$i];
$node[] = array("cat" => $cat, "children" => array(),
"selected" => ($cat->getNavigationCategory() == $currentCat->getId()));
$node = &$node[0]["children"];
if ($cat->getNavigationCategory() == $currentCat->getId())
{
$i++;
break;
}
}
// add the children of the current category
for (; $i < $navCount; $i++)
{
$cat = $navArray[$i];
$path = explode("/", $cat->getNavigationPath());
if ($path[count($path) - 3] != $currentCat->getId())
{
break;
}
$node[] = array("cat" => $cat, "children" => array(),
"selected" => ($cat->getNavigationCategory() == $currentCat->getId()));
}
// add the children of the root category
for (; $i < $navCount; $i++)
{
$cat = $navArray[$i];
$tree[] = array("cat" => $cat, "children" => array(),
"selected" => ($cat->getNavigationCategory() == $currentCat->getId()));
}
return $tree;
如果我能接受:
function addCategoryFilter($cat)
{
$path = $cat->getPath();
$select = $this->getSelect();
$id = $cat->getId();
$root = Mage::app()->getStore()->getRootCategoryId();
$commaPath = implode(", ", explode("/", $path));
$where = new Zend_Db_Expr(
"(navigation_category IN ({$commaPath})
OR navigation_parent = {$id}
OR (navigation_parent = {$root}
AND navigation_category <> {$cat->getId()}))");
$order = new Zend_Db_Expr("
CASE
WHEN navigation_category IN ({$commaPath}) THEN 1
WHEN navigation_parent = {$id} THEN 2
ELSE 3
END, LENGTH(navigation_path), navigation_name");
$select->where($where)->order($order);
return $this;
}
然后,我用我的分类块中发现下面的代码使用它两个答案,我会接受第一个和最后一个,如果我能接受一个答案为“有趣/有用”,我会在第二个答案。 :)
您选择可能将不得不加入本身,或者写一个脚本来将数据库转换为一些关系 – Shawn 2009-01-24 00:30:42
这听起来像你选择了错误的逻辑去摆在首位这一点。三个缓慢的查询,然后与PHP合并?你需要重写那部分。 – dkretz 2009-01-24 03:57:24
这听起来像你选择了错误的逻辑来首先得到这一点。三个缓慢的查询,然后与PHP合并?你需要重写那部分。谁是真正的magento给了你不理想的建议? – dkretz 2009-01-24 03:58:40