2010-06-11 120 views
1

我一直在试图想出一些东西,现在无济于事。我的MySQL知识是最基本的,所以我可以使用一些指导我应该用于以下内容:高级MySQL搜索帮助

我有2个表('圣经'和'书籍'),我需要从中搜索。现在我只是在寻找,“圣经”中有以下查询:

SELECT * 
    FROM bible 
WHERE text LIKE '%" . $query . "%' 
ORDER BY likes DESC 
    LIMIT $start, 10 

现在,我需要补充的是搜寻一些非常先进的东西另一部分。以下是我想用伪做这我知道不工作:

SELECT * 
    FROM bible 
WHERE books.book+' '+bible.chapter+':'+bible.verse = '$query' 

$查询就等于像创世纪1:2,创自books.book,1来从bible.chapter到来, 2从bible.verse

未来任何帮助/指导,非常感谢=)

+0

请用你在运行中得到的输出更新你的问题:'DESC bible' – 2010-06-11 19:56:31

回答

0

您需要首先分析查询到在PHP的书,章节和诗句。

正则表达式应该工作:

preg_match("/(.+)([0-9]+):([0-9]+)/",$query,$matches); 
$book = trim(matches[1]); // use trim to remove extra spaces 
$chapter = matches[2]; 
$verse = matches[3]; 

那么你的SQL查询变为:

SELECT * FROM bible WHERE books.book = '$book' AND bible.chapter= '$chapter' AND bible.verse ='$verse' -- watch out for sql injection here! use prepared statements!

+0

'rtrim(ltrim($ s))'='trim($ s)'?没有理由'修剪()'这个'([0-9] +)'匹配,我猜:) – jensgram 2010-06-11 20:05:24

+0

@jensgram - 正确。固定。 – 2010-06-11 20:09:51

+0

另外,在第一个子模式是贪婪的,所以它会吃掉一切。如果你只想要字母,你可以使用'\ w +',或者使用'。*?'来表示不匹配... – ircmaxell 2010-06-11 20:44:12

0

你靠近。以连接字段使用CONCAT()函数:

SELECT * FROM bible WHERE CONCAT(books.book, ' ', bible.chapter, ':', bible.verse) = '$query' 
0

您可以使用MySQL concatenation

SELECT * 
FROM bible JOIN books 
WHERE CONCAT(books.book, ' ', bible.chapter, ':', bible.verse) = '$query' 

我不知道你的外键关联书籍天书,但可能需要规范以及。

+2

这应该是最后一个选项 – 2010-06-11 20:05:10

3

我会建议在应用程序代码中设计一种方式来分解该查询,以便从关键字中分别搜索书籍,章节和诗歌。

这意味着您需要与诗歌文本分开的书,章节和诗节。

您还应该使用FULLTEXT index,因为LIKE通配符搜索为extremely inefficient

下面是我用PDO运行PHP查询:

$quoted_query = $pdo->quote($query); 
$sql = "SELECT * FROM bible 
     WHERE book = ? AND chapter = ? AND verse = ? 
      AND MATCH(text) AGAINST ({$quoted_query})" 
$stmt = $pdo->prepare($sql); 
$stmt->execute(array($book, $chapter, $verse)); 

我宁愿使用的全文查询参数太多,但MySQL不支持这一点。