我一直在谷歌搜索并搜索,但我仍然找不到答案。
所以我的问题是我想从mySQL数据库中提取当前在页面上显示的id的相关内容。在数据库中,我有一个专门用于关键字的列,我使用LIKE查询来根据这些关键字提取id。但是,我只获得一个id,因为LIKE查询按字面意思查看关键字。例如,keyword1 ='apples berries oranges'与keywords2 ='apples'' berries''oranges'不同。我想要后者,所以它可以提取更多相关数据。
我也认为我可能会接近这个错误,但我不知道有任何其他方式来提取相关项目。
这是我的代码......
<?php
include 'data/data_connect.php';
if ($sugg_qs = $db->query("SELECT * FROM questions WHERE keywords LIKE '$keywords' LIMIT 4")) {
if ($q_count = $sugg_qs->num_rows) {
echo $q_count;
while($row = $sugg_qs->fetch_assoc()) {
echo $row->title;
}
$sugg_qs->free();
} else {
die('error');
}
} else {
die('error');
}
?>
更新
if ($sugg_qs = $db->query("SELECT * FROM questions WHERE keywords LIKE CONCAT('%', '$keywords' ,'%') LIMIT 3")) {
if ($q_count = $sugg_qs->num_rows) {
$row = $sugg_qs->fetch_all(MYSQLI_ASSOC);
foreach ($row as $rows) {
echo $rows['title'];
}
} else {
die('error');
}
此代码适用于只有一个关键字的id。所以我猜一个可能的(但不受欢迎的)解决方案是为每个新关键字创建一个新列,并为每个关键字使用LIKE。
有没有办法避免创建更多列?
感谢那些已经帮助过的人:)
最终更新? 好。所以我用最可能的方式来编写代码,但显然它对我有用。所以首先我将表格标准化,其中每个元素仅限于5个关键字和1个类别。因此,在查询中,我调用具有相似关键字的项目,如果没有类似的结果,则我从原始项目中调用相同类别的项目。
这是寻找解决方案的那些(杂乱)代码!
$q_kw_arr = explode(' ', $keywords);
if ($sugg_qs = $db->query("SELECT keywords, category, title FROM questions WHERE keywords LIKE CONCAT('%', '$q_kw_arr[0]' ,'%') OR CONCAT('%', '$q_kw_arr[1]' ,'%') OR CONCAT('%', '$q_kw_arr[2]' ,'%') OR CONCAT('%', '$q_kw_arr[3]' ,'%') OR CONCAT('%', '$q_kw_arr[4]' ,'%') OR category= '$category' LIMIT 4")) {
if ($q_count = $sugg_qs->num_rows) {
$row = $sugg_qs->fetch_all(MYSQLI_ASSOC);
foreach ($row as $rows) {
echo $rows['title'];
}
} else {
echo 'error';
}
}
特别感谢..
Terminus,Grzegorz J和infidelsawyer
答案 0 :(得分:1)
您可能需要检查一下$keywords
变量中是否有任何关键字,但这是一个适用于您当前结构的解决方案。
假设字符串中的每个关键字用空格分隔:
$keywordSeparator = " ";
$keywords = explode($keywordSeparator, $keywords);
$keywordsWhere = " WHERE keywords LIKE '%" . implode("%' OR keywords LIKE '%", $keywords) . "%'";
$query = "SELECT *
FROM questions
" . $keywordsWhere;
if ($sugg_qs = $db->query($query)) {
修改强>
Paul Spiegel发表了一些好评(不只是在我的代码中指出了错误:)。
如果要避免对关键字进行部分匹配,则应将所有关键字包装在分隔符中。
为避免apple
匹配appliepie
,您可以在关键字周围存储空格。因此apple oranges
变为apple oranges
。搜索这些关键字的行为是WHERE keywords LIKE '% apple %' OR keywords LIKE '% oranges %'
。
但是,此时,如果将关键字存储在自己的表中,每行一个关键字,则应该会看到性能改进。修改后的questions
表和下面的新question_keywords
表的示例表结构:
--
-- Table structure for table `questions`
--
CREATE TABLE IF NOT EXISTS `questions` (
`question_id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(254) NOT NULL,
PRIMARY KEY (`question_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- Table structure for table `question_keywords`
--
CREATE TABLE IF NOT EXISTS `question_keywords` (
`keyword_id` int(11) NOT NULL AUTO_INCREMENT,
`question_id` int(11) NOT NULL,
`keyword` varchar(50) NOT NULL,
PRIMARY KEY (`keyword_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
--
-- Indexes for table `question_keywords`
--
ALTER TABLE `question_keywords`
ADD KEY `question_id_keyword` (`question_id`,`keyword`);
一些示例数据
INSERT INTO `questions` (`title`) VALUES ('Question #1'), ('Question #2'), ('Question #3');
INSERT INTO `question_keywords` (`question_id`, `keyword`)
VALUES
(1, 'apple')
,(2, 'orange')
,(3, 'ILikeFruit')
,(3, 'banana')
,(3, 'grape')
,(3, 'apple');
然后你可以像这样搜索
$keywordSeparator = " ";
$keywords = explode($keywordSeparator, $keywords);
$keywordsAnd = "'" . implode("','", $keywords) . "'";
$query = "
SELECT DISTINCT q.*
FROM questions q
INNER JOIN question_keywords k
ON q.question_id = k.question_id
AND k.keyword IN (" . $keywordsAnd . ")";
if ($sugg_qs = $db->query($query)) {
搜索可能看起来更复杂,因为我们现在需要JOIN
,但它应该加速,因为它不必使用%
进行搜索,并且可以利用我们对{的索引{1}}栏。
答案 1 :(得分:0)
你可以尝试:
if ($sugg_qs = $db->query("SELECT * FROM questions WHERE keywords LIKE CONCAT('%', $keywords ,'%') LIMIT 4")) {