2010-06-11 143 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不支持這一點。