MySQL在单列中使用AND

时间:2017-10-10 20:54:54

标签: php html mysql

我正在使用标记系统,在该标记系统中查询数组(标记),并选择Tag列中具有相同标记的所有行。

问题是我使用了IN条件,这是一种OR函数,它选择了所有具有相同标记的行,而不是缩小它们。例如。

不要使用像“太阳”这样的标签缩小图像范围。和' landscape'它会选择带有这些标签的所有图像。

我正在寻找的是IN()的AND版本或可以使用数组的替代品。

这只是一个例子。实际上,用户可以根据需要添加任意数量的标签

+----+---------+---------+
| ID | ImageID |   Tag   |
+----+---------+---------+
| 1  |   2     |   sun   |
+----+---------+---------+
| 2  |   12    |landscape|
+----+---------+---------+
| 3  |   15    |  field  |
+----+---------+---------+
| 4  |   15    |landscape|
+----+---------+---------+

我的代码

$tag = $_POST['tag'];
    $tag = preg_split("#/#", $tag);
    $tag = implode("', '", $tag);

    $query = "SELECT * FROM ComicStripTags WHERE `Tag` IN ('$tag')";
    $result = mysqli_query($link, $query);
    while ($row = mysqli_fetch_array($result)){
        $ID[] = $row['ImageID'];
    }

由于

P.S。我不是在SQL工作,我在PHP工作

3 个答案:

答案 0 :(得分:0)

您可以使用内部联接来执行此操作:

select * from TAGS a
inner join TAGS b
on a.ImageID = b.ImageID
where a.tag = 'field'
and b.tag = 'landscape'

根据您的PHP代码:

$joins = [];
$conditions = [];

foreach (preg_split("#/#", $_POST['tag']) as $index => $tag) {
    $alias = "ComicStripTags_$index";
    $joins[] = "ComicStripTags AS $alias" . ($index > 0 ? " ON ComicStripTags_0.ImageID = $alias.ImageID" : '');
    $conditions[] = "$alias.Tag = '$tag'";
}

$query = sprintf("SELECT * FROM %s WHERE %s", implode(' INNER JOIN ', $joins), implode(' AND ', $conditions));

答案 1 :(得分:0)

假设每个ImageID只能包含一个标记,您可以按ImageID进行分组,只选择标记数等于输入数组大小的行。

SELECT ImageID FROM ComicStripTags
WHERE Tag IN ('landscape', 'field')
GROUP BY ImageID HAVING COUNT(Tag) = 2;

答案 2 :(得分:0)

或者你可以做一些支持部分标签匹配的排名:

SELECT
  ImageID,
  group_concat(Tag) as 'matched_tags',
  count(*) as 'tag_matches'
FROM TAGS
WHERE Tag IN ( [list_of_tags] )
GROUP BY ImageID
HAVING tag_matches >= [minimum_number_of_tags]
ORDER BY tag_matches DESC