鉴于以下表格:
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 :(得分: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
答案 1 :(得分: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;