我发现这个similar question虽然我无法绕过所选择的答案,或者确定它是否适用于我的情况。
我有一个图片库的下表:
CREATE TABLE image_categories (
cat_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
parent_id INTEGER UNSIGNED DEFAULT NULL,
title VARCHAR(100) NOT NULL,
valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,
PRIMARY KEY(cat_id),
FOREIGN KEY (parent_id)
REFERENCES image_categories(cat_id)
);
CREATE TABLE image_gallery (
img_id INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
cat_id INTEGER UNSIGNED NOT NULL,
fname CHAR(45) NOT NULL,
title VARCHAR(100) DEFAULT NULL,
description VARCHAR(256) DEFAULT NULL,
create_date DATETIME NOT NULL,
valid TINYINT(1) UNSIGNED NOT NULL DEFAULT 1,
PRIMARY KEY(img_id),
FOREIGN KEY (cat_id)
REFERENCES image_categories(cat_id)
);
与文件树目录类似,类别就像文件夹一样,它们可以有子项,而这些子项可以有更多的子项创建无限层次结构。
鉴于具体cat_id
我可以按如下方式提取图像:
$sql = "SELECT * FROM image_gallery WHERE cat_id = :cat_id AND valid = TRUE";
$sth = $this->db->prepare($sql);
$sth->execute(array(':cat_id' => $cat_id));
$images = array();
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$images[$row['img_id']]['cat_id'] = $row['cat_id'];
$images[$row['img_id']]['fname'] = $row['fname'];
$images[$row['img_id']]['title'] = $row['title'];
$images[$row['img_id']]['description'] = $row['description'];
$images[$row['img_id']]['create_date'] = $row['create_date'];
$images[$row['img_id']]['valid'] = $row['valid'];
}
然而,除了任何子类别之外,我还想提取指定类别的图像,直到找不到更多的子类别。
如何实现这些结果?是使用修改过的查询还是某种类型的递归函数?
答案 0 :(得分:1)
您必须检查代码,但是这样的内容可以让您显示父类别的图像。首先,将所有相关的类别ID保存到数组中:
function get_cat_id($parent_id) {
$sql = "SELECT cat_id FROM image_categories WHERE parent_id = :parent_id AND valid = TRUE";
$sth = $this->db->prepare($sql);
$sth->execute(array(':parent_id' => $parent_id));
$category = $sth->fetch(PDO::FETCH_ASSOC);
if ($sth->rowCount() > 0) {
return $category['cat_id'];
} else {
return FALSE;
}
}
$cat_ids = array();
$parent_id = $cat_id; /* This is the $cat_id you are using now... */
while ($cat_id = get_cat_id($parent_id)) {
$cat_ids[] = $cat_id;
$parent_id = $cat_id;
}
然后,修改您的SQL查询(您可以在此处查看示例PHP - Using PDO with IN clause array):
$in = str_repeat('?,', count($cat_ids) - 1) . '?';
$sql = "SELECT * FROM image_gallery WHERE cat_id IN ($in) AND valid = TRUE";
$sth = $this->db->prepare($sql);
$sth->execute($cat_ids);
$images = array();
while ($row = $sth->fetch(PDO::FETCH_ASSOC)) {
$images[$row['img_id']]['cat_id'] = $row['cat_id'];
$images[$row['img_id']]['fname'] = $row['fname'];
$images[$row['img_id']]['title'] = $row['title'];
$images[$row['img_id']]['description'] = $row['description'];
$images[$row['img_id']]['create_date'] = $row['create_date'];
$images[$row['img_id']]['valid'] = $row['valid'];
}
编辑:抱歉,我的代码只会抱怨一个子类别。只需用此代码替换函数get_cat_id和while循环即可。我测试它,我认为它可能会起作用:
function get_subcategories($parent_id) {
global $cat_ids;
$sth = $this->db->prepare($sql);
$sth->execute(array(':parent_id' => $parent_id));
$categories = $sth->fetchAll(PDO::FETCH_ASSOC);
foreach ($categories as $category) {
$cat_ids[] = $category['cat_id'];
get_subcategories($category['cat_id']);
}
}
/* This is the $cat_id you are using now... */
$cat_ids = array($cat_id);
get_subcategories($cat_id);
其余代码(IN子句)不会改变。