php - 在where子句中使用数组,其中检查字段包含逗号分隔的单词

标签 php mysql sql arrays

请先仔细阅读问题,然后再将其标记为重复。事实并非如此。

我有一个名为 questions 的表,并且该表中有一个字段 QuestionMetaTags,它接受逗号分隔值(关键字)

这是我的表格:

`questionID` int(11) NOT NULL AUTO_INCREMENT,
`questioncategoryID` int(11) NOT NULL,
`questionstatusID` int(11) NOT NULL,
`organizationID` int(11) NOT NULL,
`legalformID` int(11) DEFAULT NULL,
`questionProtocolID` varchar(45) DEFAULT NULL,
`questionDisplayedRecordID` int(11) NOT NULL,
`questionTitle` text NOT NULL,
`questionSummary` text,
`questionText` longtext NOT NULL,
`questionAnswerSummary` text,
`questionAnswerText` longtext,
`questionMetaTags` text,
`questionAskedBy` int(11) NOT NULL,
`questionAnsweredBy` int(11) DEFAULT NULL,
`questionAskedOnDate` datetime NOT NULL,
`questionAnsweredOnDate` datetime DEFAULT NULL,
`questionAskedFromIp` varchar(255) NOT NULL

我正在尝试创建一个将“产生”相关问题的查询。我在我的页面上显示一个特定问题,并且我想在下面仅显示以下问题: 1. 属于同一类别 并且 2. 至少有2个或更多相同的关键字

在这两个变量中,我保存了所显示问题的类别和关键字,现在我想构建将显示“相关”问题的查询。

$keywordsInQurrentQuestion (array that holds the keywords)
$questioncategoryID (category of the question)

我正在尝试类似的事情:

SELECT *
   FROM question WHERE `questionstatusID` = 5
   AND questioncategoryID = $questioncategoryID
   // I have no idea how to check if the question have at least 2 keywords that exists in the $keywordsInQurrentQuestion array
   ");

我找到了有关如何在 where 子句中使用数组的答案,因为我想检查至少 2 个相同的关键字,这些答案对我没有帮助。

最佳答案

您的数据库架构并不是真正为此类查询而设计的。毕竟 MySQL 是一个关系数据库。

MySQL 中的解决方案(需要更改数据库架构)

最好有一个仅用于关键字(或元标记)的额外表格:

ID      tag
  1     oranges
  2     apples
...     ...
154     motor oil

第二个表将保存问题和标签之间的关系:

questionID tagID
  1          1
  1          2
  1         37
  2          3
...        ...
 18        102
 19        154

现在,当查询类似/相关的问题时,您可以通过检查最少的相同标签来实现。首先,使用子查询从显示的问题中获取所有标签:

SELECT tagID FROM relations WHERE questionID = 123;

这将在检索类似问题的实际查询中使用:

SELECT DISTINCT(r1.questionID)
FROM relation r1
INNER JOIN relation r2
  ON r1.questionID = r2.questionID AND NOT r1.tagID = r2.tagID
WHERE r1.tagID IN (SELECT tagID FROM relations WHERE questionID = 123)
  AND r2.tagID IN (SELECT tagID FROM relations WHERE questionID = 123)

此查询将关系表与其自身连接(自连接),查找具有相同问题 ID 但标签 ID 不同的行。在 WHERE 子句中,它检查两个连接的标签是否都在原始问题的集合内。最后,它将删除所有重复项 (DISTINCT) 并为您提供相关问题 ID 的列表。

该查询仍需扩展以检查类别,为了使语句清晰,已将其省略。

PHP 解决方案

根据您的评论,您不想更改数据库架构。虽然先从数据库检索所有问题,然后在 PHP 中获取相关问题在执行时间和性能方面可能不是最佳选择,但仍然是可能的。

假设您的原始问题的所有术语都有一定的值

$meta_tags = "oranges,apples,avocados,olive oil";

将来自同一类别的所有问题放入一个数组中,该数组至少包含问题 ID 和相应的关键字

$questions = array(
  0 => array(
    "questionID" => 1,
    "metaTags" => "apples,olive oil",
  ),
  1 => array(
    "questionID" => 2,
    "metaTags" => "oranges,motor oil",
  ),
  2 => array(
    "questionID" => 3,
    "metaTags" => "oranges,avocados",
  ),
  ...
);

您可以循环遍历您的问题,检查是否至少有两个关键字相同,然后将问题 ID 存储在某个数组中:

function check_tags($needles, $haystack) {
  $original_tags = explode(',', $haystack);
  $original_tags = array_map('trim', $original_tags);
  $tags_to_check = explode(',', $needles);
  $tags_to_check = array_map('trim', $tags_to_check);
  $count = 0;
  foreach ($tags_to_check as $t) {
    if (in_array($t, $original_tags)) {
      count++;
    }
  }
  return $count;
}
$related = array();
foreach ($questions as $q) {
  if (check_tags($q['metaTags'], $meta_tags) >= 2) {
    $related[] = $q['questionID'];
  }
}

数组 $lated 现在包含与原始问题类似的所有问题 ID。

关于php - 在where子句中使用数组,其中检查字段包含逗号分隔的单词,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36544658/

相关文章:

php - 如何获取mysql中某一个月所有产品的总和

mysql - SQL连接基于重复行的列

mysql - 复杂的 M :N relationship with MySQL tables

php - 如何在所有 Blade View 中获取全局用户配置文件数据?

php - 重定向后在 codeigniter 中销毁 session

MySQL - 使用 LEFT JOIN 进行查询并按不返回计数 0 的行进行分组

sql - 时间序列数据的孤岛和间隙问题

php - INSERT where 不存在于 php 脚本中,比较 2 个表

php - CSS 没有正确显示 .custom-logo,是 PHP 的问题吗?

mysql - 升级到新版本的 XAMPP 后从文件恢复 MySQL 数据库