Променете MYSQL заявка, за да изберете само конкретни редове, използвани като вид индекс

Пиша формуляр за търсене на обикновен форум, но не мога да намеря решение, за да избера само полетата, които ме интересуват. Таблицата на форума, наречена „Съобщения“ (MySql), използва тази структура:

MessageID - FirstMsg - Content
201 - 0 - Jack and Rose
202 - 201 - Rose
203 - 201 - Jack, Rose, David
204 - 0 - Bill
205 - 204 - Rose
206 - 0 - Rose and David
207 - 206 - David

Основният проблем е, че страницата на php форума, която използвам, разпознава съобщенията с FirstMsg 0 като "родител", а тези с FirstMsg, различни от 0, като отговори на тези с 0 и MessageID, равен на техния FirstMsg.

ес. ред с 201 като MessageID 201 е родител на 202 и 203, които ще се разглеждат като отговори на публикация 201.

С MySql заявка и php лесно получавам съдържанието:

$MySql = "SELECT * FROM Messages WHERE Content LIKE '%$Search%'" ORDER BY Date DESC LIMIT 1, 30";
$Result = mysql_query($MySql);
while($rs = mysql_fetch_array($Result)) {

}

Например, търсейки Rose, получавам, повтаряйки съдържанието в цикъла while:

201 - 0 - Jack and Rose
202 - 201 - Rose
203 - 201 - Jack, Rose, David
205 - 204 - Rose
206 - 0 - Rose and David

Когато трябва да получа, със заявка, само "родителските" елементи, дори и на "Роза" не присъства в родителското съобщение, а само в един от отговорите, като:

201 - 0 - Jack and Rose
204 - 0 - Bill
206 - 0 - Rose and David

Възможно ли е да направите това, като промените само MySql заявката? Имам нужда от това, защото самата заявка се използва сред една и съща страница за навигация между „страниците“, генерирани от php, когато техният брой се увеличи след максималните съобщения за номер на страница. Благодаря предварително за всяка помощ.


person Sofia    schedule 21.01.2011    source източник
comment
В бъдеще, моля, отделете време, за да форматирате кода във вашия въпрос по подходящ начин (използвайки контролата на редактора {}).   -  person John Parker    schedule 21.01.2011


Отговори (2)


Ако искате да получавате само родителските съобщения:

SELECT DISTINCT p.*
FROM Messages m JOIN Messages p
    ON m.FirstMsg = p.MessageID
        OR (m.FirstMsg = 0 AND m.MessageID = p.MessageID)
WHERE m.Content LIKE '%$Search%'
ORDER BY m.Date DESC LIMIT 1, 30

Ако искате да сортирате по родителското съобщение, променете m.Date на p.Date

person The Scrum Meister    schedule 21.01.2011
comment
Опитах кода, но получавам много дублиращи се отговори. Възможно ли е да ги избегнем? Благодаря за вашият отговор :) - person Sofia; 21.01.2011
comment
Благодаря, сега работи добре. Изисква много време за попълване на заявката, това нормално ли е? - person Sofia; 21.01.2011
comment
Освен ако не използвате пълнотекстово търсене, това ще отнеме време. - person The Scrum Meister; 21.01.2011
comment
Как да използвам пълнотекстово търсене? - person Sofia; 21.01.2011

По принцип трябва да филтрирате резултатите по следния начин:

 - set finalResultSet as nothing
 - if the FirstMsg = 0 : then union MessageID with finalResultSet
 - else : union FirstMsg with finalResultSet

Можете да направите филтриращата част в PHP с горните условия.

За да го филтрирам в mysql, мислех за нещо подобно:


(
    SELECT MessageID FROM Messages
    WHERE 
        FirstMsg=0 AND
        Content LIKE '%$Search%'
    ORDER BY Date DESC LIMIT 1, 30
)
UNION
(
    SELECT FirstMsg FROM Messages
    WHERE 
        Content LIKE '%$Search%'
    ORDER BY Date DESC LIMIT 1, 30
)

Силно неефективен. Не съм добър в MySQL заявките. Но със сигурност схващате идеята, нали? Плюс това, сигурен съм, че тук има много експерти, които ще предложат по-добро решение. Късмет! :-)

person UltraInstinct    schedule 21.01.2011
comment
В php направих филтрирането и то работи, но основният проблем беше, че не можех да го използвам за навигация между страниците. Mysql не получава, странно, никакъв ред като резултат. Все пак благодаря за отговора :) - person Sofia; 21.01.2011