我正在尝试使用标签构建搜索功能
MySQL中的数据结构
parts parts_to_tags tags
---------------------- ---- ------------------- -----------------
| part_id | part_name | |id|part_id|tag_id| |tag_id|tag_name|
| 1 | 20lb Sledge | | 1| 1| 1| | 1|Hammer |
| 2 | Framing Hammer| | 2| 1| 2| | 2|Sledge |
| | | | 3| 2| 1|
我有一个用户在数组中提供的标签列表,我想将它与这些表进行比较以返回所有结果,因此如果用户要求锤子,则应返回两个工具,但是如果他们要求两个或只是雪橇只应返回20磅的雪橇。我不想使用SQL“IN”,因为我想将其用作向下钻取,而不是存在任何标记但是结果必须存在所有标记。
我的代码:
$keywords = $_POST['tags'];
// Returns: Array ( [0] => Sledge [1] => Hammer )
$getInventory = $conn -> prepare("SELECT * FROM
parts
LEFT JOIN parts_to_tags ON parts.part_id = parts_to_tags.part_id
LEFT JOIN tags ON parts_to_tags.tag_id = tags.tag_id
");
$getInventory -> execute();
$partArray = $getInventory -> fetchAll();
$matched = !array_diff($keywords, $partArray);
print_r($matched);
但是,$ partArray似乎是一个深度数组,所以我不能使用array_diff。有没有人有不同的方法去做?我尝试过使用几种不同的fetch类型,但是我一直在array_diff上获得数组到字符串的转换错误。
由于
答案 0 :(得分:1)
查询中没有WHERE
子句;它会返回整个表,这不是你需要的。更多,即使您添加WHERE
子句,LEFT JOIN
仍会返回您需要的更多行。
您问题的可能解决方案可能是:
SELECT p.part_id, p.part_name, GROUP_CONCAT(t.tag_name ORDER BY t.tag_name SEPARATOR '|') AS tags
FROM parts p
INNER JOIN parts_to_tags pt ON p.part_id = pt.part_id
INNER JOIN tags t ON pt.tag_id = t.tag_id
WHERE t.tag_name IN ('Hammer', 'Sledge')
GROUP BY p.part_id
它选择至少包含一个标签的部件以及与每个部件关联的标签列表,按升序排序并用“|”分隔。
当然,IN ()
条件中的标记名称列表将在$keywords
的PHP代码中生成。
运行查询后的PHP
代码:
// Sort the keywords ascending
sort($keywords);
// Concatenate them, use '|' as separator
$allTags = implode('|', $keywords);
// Get the result set
$parts = array();
foreach ($getInventory -> fetchAll() as $row) {
// Keep only the parts that have all the tags
if ($row['tags'] == $allTags) {
$parts[] = $row;
}
}
UPDATE:查询的简化版本,仅返回包含所有指定标记的部分(不需要额外的PHP处理):
SELECT p.part_id, p.part_name, COUNT(t.tag_name) AS nbTags
FROM parts p
INNER JOIN parts_to_tags pt ON p.part_id = pt.part_id
INNER JOIN tags t ON pt.tag_id = t.tag_id
WHERE t.tag_name IN ('Hammer', 'Sledge') # <----------------+
GROUP BY p.part_id # |
HAVING nbTags = 2 # The number of strings in this list ---+
答案 1 :(得分:0)
如果我理解正确,您可以解决如下问题。多维数组diff
function arrayRecursiveDiff($aArray1, $aArray2) {
$aReturn = array();
foreach ($aArray1 as $mKey => $mValue) {
if (array_key_exists($mKey, $aArray2)) {
if (is_array($mValue)) {
$aRecursiveDiff = arrayRecursiveDiff($mValue, $aArray2[$mKey]);
if (count($aRecursiveDiff)) { $aReturn[$mKey] = $aRecursiveDiff; }
} else {
if ($mValue != $aArray2[$mKey]) {
$aReturn[$mKey] = $mValue;
}
}
} else {
$aReturn[$mKey] = $mValue;
}
}
return $aReturn;
}
$arr1 = arrayRecursiveDiff($big_array,$small_array);