2012-01-04 62 views
1

我目前正在嘗試更新我的內部搜索引擎以使用多個單詞。這是非常龐大而複雜的,但我遇到了現在從未遇到過的錯誤,我不知道爲什麼。巨大的SQL查詢返回錯誤(mysql)

所以問題是,爲什麼我收到下面的錯誤?

我將把它分成不同的部分以便更好地理解。

這僅僅是一個SQL查詢我echo d,複製並粘貼到PHPMyAdmin中,粘貼在這裏(的phpMyAdmin格式化好聽),它搜索2個詞語的數據庫:

SELECT * 
FROM (

SELECT p.page_url AS url, COUNT(*) AS occurrences 
FROM PAGE p, word w, occurrence o 
WHERE (
(
p.page_id = o.page_id 
AND w.page_word_id = o.page_word_id 
AND w.word_word LIKE '%' 'test' '%' 
GROUP BY p.page_id 
) 
OR (
p.page_id = o.page_id 
AND w.page_word_id = o.page_word_id 
AND w.word_word LIKE '%' 'search' '%' 
GROUP BY p.page_id 
) 
UNION (

SELECT f.file_url AS url, COUNT(*) AS occurrences 
FROM files f, filenames fn, fileoccurrence fo 
WHERE f.file_id = fo.file_id 
AND fn.file_word_id = fo.file_word_id 
AND fn.file_word LIKE '%' 'test' '%' 
GROUP BY f.file_id 
) 
OR (

SELECT f.file_url AS url, COUNT(*) AS occurrences 
FROM files f, filenames fn, fileoccurrence fo 
WHERE f.file_id = fo.file_id 
AND fn.file_word_id = fo.file_word_id 
AND fn.file_word LIKE '%' 'search' '%' 
GROUP BY f.file_id 
) 
)t 
ORDER BY occurrences DESC 

此代碼是由生產下面從搜索輸入

// Do a little formatting 
$keyword = strtolower($keyword); 

// Get timestamp for start 
$start_time = microtime(true); 

$searched_words = explode(' ', $keyword); 

foreach ($searched_words as $index => $word) { 
    // Set up the stemmer 
    $stemmer = new PorterStemmer; 
    $stemmed_string = $stemmer->stem($word); 
    $searched_words[$index] = $stemmed_string; 
} 

// Configure the sql code 
$sql = "SELECT * FROM (SELECT p.page_url AS url, COUNT(*) AS occurrences 
    FROM page p, word w, occurrence o WHERE ("; 

// Add the extra words to the sql 
foreach ($searched_words as $index => $word) { 
    $sql .= "(p.page_id = o.page_id AND w.page_word_id = o.page_word_id 
     AND w.word_word LIKE '%' '" . $word . "' '%' GROUP BY p.page_id) OR"; 
} 
// Add the union to the sql and then add the second query 
$sql = substr($sql, 0, (strLen($sql)-3)); //this will eat the last OR 
$sql .= " UNION "; 

// The second set of querys 
foreach ($searched_words as $index => $word) { 
    $sql .= "(SELECT f.file_url AS url, COUNT(*) AS occurrences FROM files f, filenames fn, fileoccurrence fo 
     WHERE f.file_id = fo.file_id AND fn.file_word_id = fo.file_word_id AND fn.file_word 
     LIKE '%' '" . $word . "' '%' GROUP BY f.file_id) OR"; 
} 

// Clsoe the sql code 
$sql = substr($sql, 0, (strLen($sql)-3)); //this will eat the last OR 
$sql .= ") t ORDER BY occurrences DESC"; // LIMIT " . $results . ""); 

// echo the query for the pure lolz of it 
echo $sql . "<br /><br />"; 

// Search the DB for the results 
$results = mysql_query($sql) 
    or die("Invalid query: " . mysql_error()); 

所有這一切都使用爆炸功能的PHP代碼返回錯誤:

Invalid query: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'GROUP BY p.page_id) OR(p.page_id = o.page_id AND w.page_word_id = o.page_word_id' at line 3

爲什麼我收到此錯誤?我以前使用的代碼工作正常。我添加的唯一真實的東西是foreach()

這是我原來的SQL代碼:

$result = mysql_query("SELECT * FROM (SELECT p.page_url AS url, COUNT(*) AS occurrences 
    FROM page p, word w, occurrence o WHERE p.page_id = o.page_id AND w.page_word_id = o.page_word_id 
    AND w.word_word LIKE '%' '" . $stemmed_string . "' '%' GROUP BY p.page_id UNION 
    SELECT f.file_url AS url, COUNT(*) AS occurrences FROM files f, filenames fn, fileoccurrence fo 
    WHERE f.file_id = fo.file_id AND fn.file_word_id = fo.file_word_id AND fn.file_word 
    LIKE '%' '" . $stemmed_string . "' '%' GROUP BY f.file_id) t ORDER BY occurrences DESC") // LIMIT " . $results . "") 
     or die("Invalid query: " . mysql_error()); 

編輯:修正了上述錯誤。與此代碼

// Configure the sql code 
$sql = "SELECT * FROM (SELECT p.page_url AS url, COUNT(*) AS occurrences 
    FROM page p, word w, occurrence o WHERE ("; 

// Add the extra words to the sql 
foreach ($searched_words as $index => $word) { 
    $sql .= "(p.page_id = o.page_id AND w.page_word_id = o.page_word_id 
     AND w.word_word LIKE CONCAT('%', '" . $word . "', '%'))) OR "; //GROUP BY p.page_id) 
} 
// Add the union to the sql and then add the second query 
$sql = substr($sql, 0, (strLen($sql)-4)); //this will eat the last OR 
$sql .= " GROUP BY p.page_id)"; 
$sql .= " UNION "; 
$sql .= "(SELECT f.file_url AS url, COUNT(*) AS occurrences FROM files f, filenames fn, fileoccurrence fo 
    WHERE ("; 

// The second set of querys 
foreach ($searched_words as $index => $word) { 
    $sql .= "(f.file_id = fo.file_id AND fn.file_word_id = fo.file_word_id AND fn.file_word 
     LIKE CONCAT('%', '" . $word . "', '%'))) OR "; //GROUP BY f.file_id) 
} 

// Clsoe the sql code 
$sql = substr($sql, 0, (strLen($sql)-4)); //this will eat the last OR 
$sql .= " GROUP BY f.file_id)"; 
$sql .= ") t ORDER BY occurrences DESC"; // LIMIT " . $results . ""); 

現在,這會產生錯誤:

Invalid query: Every derived table must have its own alias

其中有事情做與工會(我不是在工會很好..或SQL一般)

回答

4

您只能通過將它們放在一起來連接SQL中的字符串。

AND w.word_word LIKE '%' 'test' '%' 

應該

AND w.word_word LIKE CONCAT('%', 'test', '%') 

或者,如果您使用SET SQL_MODE='PIPES_AS_CONCAT'獲得標準ANSI SQL語法,你可以使用:

AND w.word_word LIKE '%' || 'test' || '%' 

回覆你的評論,我看到了另一個問題:

在SQL中,在添加GROUP BY子句之前,WHERE子句必須完整。語法是:

WHERE (<conditions...>) 
GROUP BY <expressions> 

鑑於你有:

WHERE (<conditions...> GROUP BY <expressions>) 
    OR (<conditions...> GROUP BY <expressions>) 

你有什麼是不合法的語法。

真的,這是你應該能夠在SQL的任何初學者參考中查找自己的東西。


Every derived table must have its own alias

這意味着您在使用子查詢FROM子句,但沒有給它一個別名。例如:

SELECT ... FROM (SELECT ... FROM table) AS x WHERE ...etc... 

如果你離開了AS x那麼它是一個錯誤(x是在這種情況下只是一個例子,你可以選擇一個更有意義的別名)。

0

在您生成的SQL中,括號不匹配...有9'('和8')。

您是否也將LIMIT " . $results . "");作爲最後一次代碼更改的一部分進行了註釋?