Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / сложности в, казалось бы, простой задаче / 4 сообщений из 4, страница 1 из 1
28.04.2010, 19:10
    #36603976
itron
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сложности в, казалось бы, простой задаче
Долго пытаюсь нормально решить задачу. Задача следующая.
Есть рубрики. Есть новости. У каждой новости есть одна рубрика.
Требуется наиболее быстро и правильно получить максимум по N новостей из каждой рубрики, отсортированных по названию рубрики по возрастанию и по дате создания новости по убыванию.
Как думаете, это вообще возможно сделать базовыми средствами SQL, не прибегая к созданию функций и прочему подобному?

Пока что решил задачу двумя запросами (выборка по 2 новости) с промежуточной и последующей обработками на стороне клиента БД:
1)
SELECT
`news`.`rubric_id` as `rubric_id`,
LEFT(GROUP_CONCAT(LPAD(`news`.`id`,3,'0') ORDER BY `news`.`created` desc),7) AS `id`
FROM `news`
LEFT JOIN `rubrics`
ON `rubrics`.`id` = `news`.`rubric_id`
GROUP BY `news`.`rubric_id`
ORDER BY `rubrics`.`title` asc;
2) Разбираю ответ, подставляю полученные значения id во второй запрос.
3) SELECT * FROM `news` WHERE `id` IN (id1,id2,id3,...);
4) Сортирую результат второго запроса на стороне клиента БД в соответствии с порядком, полученным в ходе разбора первого запроса.

Самое удивительное, что этот ужас работает.

Если у кого-то возник вопрос "а почему не выбирать отдельными запросами из каждой рубрики?", прошу представить, что будет происходить в реальности, если рубрик становится несколько десятков, а сервер БД, например, расположен на другом континенте и, следовательно, накладные расходы на каждый запрос к базе данных становятся достаточно большими.

Дамп базы (MySQL):

CREATE TABLE `news` (
`id` int(10) unsigned NOT NULL auto_increment,
`rubric_id` int(10) unsigned default NULL,
`title` varchar(255) default NULL,
`created` date default NULL,
PRIMARY KEY (`id`)
);

CREATE TABLE `rubrics` (
`id` int(10) unsigned NOT NULL auto_increment,
`title` varchar(255) default NULL,
PRIMARY KEY (`id`)
);

insert into `news`(`id`,`rubric_id`,`title`,`created`) values (3,1,'Из-за наводнения в Сибири перекрыли федеральную трассу','2010-04-28'),(2,1,'Из-за штормового ветра во Владивостоке перестали ходить паромы','2010-04-27'),(1,1,'На севере Москвы при взрыве газа погиб человек','2010-04-26'),(5,2,'Совет Федерации ратифицировал соглашение по Черноморскому флоту','2010-04-28'),(4,2,'Чавес обвинил Колумбию в причастности к разведоперациям США','2010-04-27'),(6,3,'Россия не сможет сократить дефицит бюджета за счет роста цен на нефть','2010-04-27');

insert into `rubrics`(`id`,`title`) values (1,'происшествия'),(2,'политика'),(3,'экономика');

PS. На самом деле, база гораздо сложнее, но я специально упростил постановку задачи, чтобы узнать существует ли нормальный способ решения такого класса задач.
...
Рейтинг: 0 / 0
28.04.2010, 19:39
    #36604019
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сложности в, казалось бы, простой задаче
itronТребуется наиболее быстро и правильно получить максимум по N новостей из каждой рубрики, отсортированных по названию рубрики по возрастанию и по дате создания новости по убыванию.
Как думаете, это вообще возможно сделать базовыми средствами SQL, не прибегая к созданию функций и прочему подобному?Если бы вы писали топик в нужном подфоруме, то могли бы обнаружить, что там это даже в FAQ-е прописано. тынц1 и тынц2 .
...
Рейтинг: 0 / 0
28.04.2010, 20:53
    #36604129
itron
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сложности в, казалось бы, простой задаче
Насколько я понимаю, решение задачи через номера строк результата имеет серьезное ограничение - такой подход будет весьма неэффективен при большом числе записей и полей в таблице.

Мой вопрос - возможно ли решить упомянутую задачу базовыми средствами SQL наиболее быстро и правильно? Или применимы только разные не оптимальные методы? И задача не зависит от используемой конкретно СУБД. Заданный вопрос не относится к конкретике MySQL.

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

Приведенный в первом сообщении метод и решение через нумерацию строк - это единственные способы решения задачи или есть более оптимальный вариант?
...
Рейтинг: 0 / 0
29.04.2010, 09:38
    #36604491
miksoft
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
сложности в, казалось бы, простой задаче
itronНасколько я понимаю, решение задачи через номера строк результата имеет серьезное ограничение - такой подход будет весьма неэффективен при большом числе записей и полей в таблице.Эффективнее можно, но это будет уже не один запрос, а много.itronМой вопрос - возможно ли решить упомянутую задачу базовыми средствами SQL наиболее быстро и правильно? Или применимы только разные не оптимальные методы?По моим ощущениям - базовыми средствами SQL решить это можно, но придется писать отдельный запрос для каждого N и работать это будет очень медленно. Более-менее оптимально, имхо, можно решить только СУБД-специфичными методами.itronЗаданный вопрос не относится к конкретике MySQL.Тем не менее, представленный запрос является именно MySQL-специфичным.
...
Рейтинг: 0 / 0
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / сложности в, казалось бы, простой задаче / 4 сообщений из 4, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]