2012-01-04 55 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 . "");作为最后一次代码更改的一部分进行了注释?