【问题标题】:Huge sql query returning an error (mysql)巨大的 sql 查询返回错误(mysql)
【发布时间】:2012-02-01 23:52:10
【问题描述】:

我目前正在尝试更新我的内部搜索引擎以使用多个词。它非常庞大且复杂,但我遇到了以前从未遇到过的错误,我不知道为什么。

所以问题是,为什么我会收到以下错误?

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

这只是我echod的SQL查询,复制并粘贴到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 

此代码由下面的 PHP 代码生成,该代码使用搜索输入中的爆炸函数

// 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());

所有这些都返回错误:

无效查询:您的 SQL 语法有错误;检查手册 对应于您的 MySQL 服务器版本以获得正确的语法 在 'GROUP BY p.page_id) OR(p.page_id = o.page_id AND w.page_word_id = o.page_word_id' 在第 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 . "");

这会产生错误:

无效查询:每个派生表都必须有自己的别名

这与联合有关(我不太擅长联合......或一般的 SQL)

【问题讨论】:

    标签: php mysql concat


    【解决方案1】:

    在 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 中,必须先完成 WHERE 子句,然后才能添加 GROUP BY 子句。语法是:

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

    而你有:

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

    你所拥有的不是合法的语法。

    真的,这是您应该能够在任何 SQL 初学者参考资料中自行查找的内容。


    每个派生表都必须有自己的别名

    这意味着您在 FROM 子句中使用了子查询,但没有给它一个别名。例如:

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

    如果你省略了AS x,那么这是一个错误(x 只是这种情况下的一个例子,你可以选择一个更有意义的别名)。

    【讨论】:

      【解决方案2】:

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

      您是否也注释掉了 LIMIT " . $results . ""); 作为您上次代码更改的一部分?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-03-20
        • 1970-01-01
        • 2013-11-07
        • 2016-12-16
        • 1970-01-01
        • 2014-02-15
        • 2014-02-20
        相关资源
        最近更新 更多