2017-05-25 65 views
0

给定如下表:匹配项目动态

CREATE TABLE catalog_categories (
    cat_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT, 
    parent_id INTEGER UNSIGNED DEFAULT NULL, 
    title VARCHAR(255) NOT NULL, 
    valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1, 

    PRIMARY KEY(cat_id), 
    FOREIGN KEY (parent_id) 
    REFERENCES catalog_categories(cat_id) 
); 

CREATE TABLE catalog_item_categories (
    item_id INTEGER UNSIGNED NOT NULL, 
    cat_id INTEGER UNSIGNED NOT NULL, 
    valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1, 

    FOREIGN KEY (item_id) 
    REFERENCES catalog_items(item_id), 
    FOREIGN KEY (cat_id) 
    REFERENCES catalog_categories(cat_id) 
); 

而一个多维阵列作为输入,其中key => parent_id, value => cat_ids

["categories"]=> 
array(2) { 
    [1]=> 
    array(2) { 
    [0]=> 
    string(1) "5" 
    [1]=> 
    string(1) "6" 
    } 
    [2]=> 
    array(1) { 
    [0]=> 
    string(2) "12" 
    } 
} 

我试图仅选择匹配所提供的项目类别。

SELECT a.item_id 
FROM  catalog_items AS a 
JOIN  catalog_item_categories AS b ON a.item_id = b.item_id 
JOIN  catalog_categories AS c ON b.cat_id = c.cat_id AND c.parent_id = 1 AND c.cat_id IN ('5', '6') 
JOIN  catalog_categories AS d ON b.cat_id = d.cat_id AND d.parent_id = 2 AND d.cat_id IN ('12') 
WHERE  a.valid = TRUE 
      AND b.valid = TRUE 
      AND c.valid = TRUE 
      AND d.valid = TRUE 

这是我的硬编码尝试,但有没有更好的方法,或者我该如何动态构建此查询?只要我不知道有多少parent => child会有关系。

+0

我不明白'parent_id'。你能提供样本数据和期望的结果吗? –

+0

类别可以有子类别... –

回答

1

考虑通过分类循环,构建一个动态PHP字符串的SQL查询。如果阵列中的数据从用户输入派生当然,使用parameterization代替concatentation的:

$categories = [ 
    1 => array("5","6"), 
    2 => array("12") 
]; 

$sql = "SELECT a.item_id 
     FROM catalog_items AS a 
     JOIN catalog_item_categories AS b ON a.item_id = b.item_id";    
$i = 1; 
foreach($categories as $k=>$v){   
    $cats = implode(",", $v);  

    $sql = $sql." 
     JOIN catalog_categories AS c$i ON b.cat_id = c$i.cat_id AND c$i.parent_id = $k 
      AND c$i.cat_id IN ($cats) AND c$i.valid = TRUE";  
    $i = $i + 1; 
} 

$sql = $sql. 
     "\nWHERE a.valid = TRUE AND b.valid = TRUE"; 

echo $sql; 

输出

SELECT a.item_id 
FROM catalog_items AS a 
JOIN catalog_item_categories AS b ON a.item_id = b.item_id 
JOIN catalog_categories AS c1 ON b.cat_id = c1.cat_id AND c1.parent_id = 1 
    AND c1.cat_id IN (5,6) AND c1.valid = TRUE 
JOIN catalog_categories AS c2 ON b.cat_id = c2.cat_id AND c2.parent_id = 2 
    AND c2.cat_id IN (12) AND c2.valid = TRUE 
WHERE a.valid = TRUE AND b.valid = TRUE 
0

您可以用聚集的查询,这可能是简单的构造做到这一点:

select cic.item_id 
from catalog_item_categories cic 
group by cic.item_id 
where sum(cic.cat_id in (5, 6) and cic.valid = 1) > 0 and 
     sum(cic.cat_id in (12) and cic.valid = 1) > 0; 
+0

我有点困惑。此解决方案不检查项目是否有效(您遗漏了'catalog_items'),​​它忽略了用于将子项关联到其父类别的'parent_id'。 –

+0

您也遗漏了'catalog_categories',所以它不检查该类别是否有效。 –