SQL запрос для выбора новостей по нескольким темам

dak

Guest
SQL запрос для выбора новостей по нескольким темам

Задача состоит в том, чтобы переписать SQL запрос, а может, если надо и оптимизировать текущую схему, для реализации выбора из базы новостей, которые принадлежат сразу всем "темам" из некоторого списка. На текущий момент имеется следующая реализации, и она успешно работает. Но есть подозрение, что можно сделать как-то лучше, а то шибко запрос тяжелый.


Реализация выбора сообщений по нескольким темам:

-------------------------------------------------------------------------------
-- Table structure for table 'News'
-- Таблица новостей
-------------------------------------------------------------------------------
create table News
(
NewsId int(11) not null auto_increment,
Body text,

primary key (NewsId)
) type=MyISAM;

-------------------------------------------------------------------------------
-- Table structure for table 'Topics'
-- Таблица тем новостей (топиков)
-------------------------------------------------------------------------------
create table Topics
(
TopicId int(11) not null auto_increment,
Description text,

primary key (TopicId)
) type=MyISAM;

-------------------------------------------------------------------------------
-- Table structure for table 'News_Topic'
-- Таблица перевязки новость-тема
-------------------------------------------------------------------------------
create table News_Topic
(
NewsId int(11) default null,
TopicId int(11) default null

primary key (NewsId, TopicId)
) type=MyISAM;


-------------------------------------------------------------------------------
SQL запрос
-------------------------------------------------------------------------------

$MsgFilter - имя новой временной таблицы
$MidString - id-шники топиков через запятую по которым мы выбираем
$TopicsNum - число этих id-шников


create temporary table $MsgFilter
select NewsId
from news_topic
where TopicId in ($MidString)
group by NewsId
having count(TopicId) = $TopicsNum;

После выполнения запроса в таблице $MsgFilter содержаться id-шники всех
новостей, имеющие все темы из спика.

Буду рад, если кто-то поделится своими идеями и соображениями. Идея-то в подобной веще не нова, и думаю, сталкивалис с нею многие.
 

tony2001

TeaM PHPClub
не стоит НАСТОЛЬКО многословно объяснять - никто это читать не будет.
в двух словах объясни проблему.
 

dak

Guest
Извини, но что может быть проще схемы, из которой я выкинул все лишнее и оставил только относящееся с данному вопросу? Сейчас подправил удалив комментарии из SQL запроса, чтобы лучше воспринималось.

Ладно, поясню:
Задача состоит в реализации на базе MySQL механизма хранения а базе новостей, которые могут присваиваться нескольким "темам", которые так же хранятся в базе. Чтобы можно было отбирать только те новости, которые "имеют" все темы из списка, а не только отбор по одной теме.

Предложенное мною решение кажется мне далеко не самым хорошим!
 

dak

Guest
Нет, переменное. Сколько для сайта будет надо столько и будет создано. Закладываться на статическое их число нельзя. Другое дело, что при отбор редко понадобится скажем больше 2-3 тем, но и на это так же не хотелось бы закладываться, чтобы не иметь подобные ограничения.

Посмотри все-таки пожалуйста мое первое сообщение, из Схемы и Запроса должно быть понятнее, что надо. Так как это работающией пример.
 

Demiurg

Guest
Думаю примерно так:
select @topics = count(*) from Topic;
select news.NewsId , count(News_Topics.TopicId) TopicCnt from News , News_Topics where News.NewsId = News_Topics.NewsId group by news.NewsId having TopicCnt = @topics
 

Яро

бард-скальд
select @topics = count(*) from Topic;
select news.NewsId , count(News_Topics.TopicId) TopicCnt from News , News_Topics where News.NewsId = News_Topics.NewsId group by news.NewsId having TopicCnt = @topics
Любопытно, Demiurg, а можно прокомментировать этот MySQL код. Если не трудно.
 

Demiurg

Guest
Сначала расчитываем общее количество тем, и заносим это в переменную @topic. Потом для каждой новости считаем количество тем к которой она привязана, и отрезаем новости у которых это количество меньше @topic.
 
Сверху