提问人:Cyclopic 提问时间:11/18/2020 最后编辑:NickCyclopic 更新时间:11/18/2020 访问量:96
选择所有提交的复选框值都存在于 mySQL 列 [duplicate] 中以逗号分隔字符串形式的所有行
Select all rows where all submitted checkbox values exist in comma separated strings in mySQL column [duplicate]
问:
我希望能够只将所有提交的行都存在于 中。我的代码选择具有任何已提交复选框值的行。SELECT
WHERE
checkbox values
keyWords
我有一个带有表格照片的mySQL数据库PhotoArchive
| id | title |filePath | keyWords |
| 1 | mypic1 |imgs/pic1.jpg | Mono,Portrait (etc) |
| 2 | mypic1 |imgs/pic2.jpg | Colour,Portrait (etc) |
| 3 | mypic2 |imgs/pic2.jpg | Mono,Landscape (etc) |
| 4 | mypic2 |imgs/pic2.jpg | Colour,Landscape (etc)|
我有一个带有复选框表单的 html 页面
<form action="selectFromDb.php" method="get">
<input type="checkbox" value="Mono" name="category[]" id="OptMono" />
<label for="OptMono"> Monochrome</label>
<input type="checkbox" value="Colour" name="category[]" id="OptColour" />
<label for="OptColour"> Colour</label>
<input type="checkbox" value="Portraits" name="category[]" id="OptPortraits" />
<label for="OptPortraits"> Portraits</label>
<input type="checkbox" value="Landscape" name="category[]" id="OptLandscape" />
<label for="OptLandscape"> Landscape</label>
<input type="submit" value="Submit" />
以及使用此 SELECT 语句selectFromDb.php文件 <? foreach($_GET['category'] as $category){
$categories[] = $category;
}
$total_imgs_sql = "SELECT id, title, filePath FROM photos WHERE keyWords LIKE '%$category%'
?>
这将返回 中任何值所在的行。我只想返回所有$category关键字都存在的行。$category
keyWords
WHERE
如何实现这一目标?
(完整版有近 200 个复选框,每行可以有大约 20 个逗号分隔的单词)
谢谢keyWords
答:
1赞
Nick
11/18/2020
#1
为此,您可以在查询中构建一个类别值表,然后将其发送到该表中,并且仅选择返回与类别值表中行数相同的照片。作为示例查询,要查找包含和类别的照片,请执行以下操作:JOIN
photos
Colour
Portrait
SELECT p.*
FROM (
SELECT 'Colour' AS keyWord
UNION ALL
SELECT 'Portrait' AS keyWord
) k
JOIN photos p ON CONCAT(',', p.keyWords, ',') LIKE CONCAT('%,', k.keyWord, ',%')
GROUP BY p.id
HAVING COUNT(*) = 2
在 PHP 中,您可以像这样生成此查询:
$categories = array('Colour', 'Portrait');
$sql = "SELECT p.*\nFROM (\n SELECT '";
$sql .= implode("' AS keyword\n UNION ALL\n SELECT '", $categories);
$sql .= "' AS keyWord\n) k\nJOIN photos p ON CONCAT(',', p.keyWords, ',') LIKE CONCAT('%,', k.keyWord, ',%')\n";
$sql .= "GROUP BY p.id\nHAVING COUNT(*) = " . count($categories);
3v4l.org 上的PHP演示
请注意,为了便于阅读,我保留了使输出查询与上述查询匹配;您可以将它们替换为 (空格)。\n
另请注意,您可能对 SQL 注入持开放态度,您应该检查值以确保它们有效(使用关键字白名单),或转换为准备好的语句以避免这种情况。以下是使用预准备语句的方法(假设您使用的是 mysqli 并且您的连接在):$category
$conn
$categories = array('Colour', 'Portrait');
$sql = "SELECT p.*\nFROM (\n SELECT ";
$sql .= implode(" AS keyword\n UNION ALL\n SELECT ", array_fill(0, count($categories), '?'));
$sql .= " AS keyWord\n) k\nJOIN photos p ON CONCAT(',', p.keyWords, ',') LIKE CONCAT('%,', k.keyWord, ',%')\n";
$sql .= "GROUP BY p.id\nHAVING COUNT(*) = " . count($categories);
$stmt = $conn->prepare($sql);
$stmt->bind_param(str_repeat('s', count($categories)), ...$categories);
$stmt->execute();
$result = $stmt->get_result();
foreach ($result as $row) {
print_r($row);
}
另请注意,如果您在后者中拥有每张照片/关键字组合一行的表格,而不是使用逗号分隔的数据,这将更简单(我强烈建议您阅读此问答)。keywords
photo_keywords
评论
0赞
Nick
11/18/2020
@Dharman时间不多了,不得不去开会。我已经更新了答案。
0赞
Nick
11/18/2020
@Dharman实际上这个问题最初是被标记的,我把它改成了mysqli
mysql
0赞
Cyclopic
11/18/2020
@Nick 非常感谢您非常慷慨的帮助 - 对我来说已经足够了。由于我缺乏经验,我需要一点时间来理解你的答案。如果我被卡住了(我想我可能会!我会在这里再次发表评论。
0赞
Nick
11/18/2020
@Cyclopic不用担心 - 我希望这是有用的。如果您有任何后续疑问,请再次评论,我会尽快回答。
评论