2017-05-25 67 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',所以它不檢查該類別是否有效。 –