Огромный SQL-запрос, возвращающий ошибку (MySQL) - PullRequest
1 голос
/ 04 января 2012

В настоящее время я пытаюсь обновить свою внутреннюю поисковую систему, чтобы использовать несколько слов.Это очень большой и сложный, но я сталкиваюсь с ошибками, с которыми я никогда не сталкивался раньше, и я понятия не имею, почему.

, поэтому вопрос в том, почему я получаю ошибку ниже?

Я собираюсь разделить это на различные разделы для лучшего понимания.

Это просто 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 

Этот код создается с помощью приведенного ниже 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) ИЛИ (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 в целом)

Ответы [ 2 ]

4 голосов
/ 04 января 2012

Вы не можете объединять строки в 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 - просто пример, вы можете выбрать более значимый псевдоним).

0 голосов
/ 04 января 2012

В сгенерированном SQL скобки не совпадают ... есть 9 '(' s и 8 ')'.

Вы также закомментировали LIMIT " . $results . ""); как часть вашего последнего изменения кода?

...