SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 26.01.2011 17:32:19

nikolajtesla
Завсегдатай
Зарегистрирован: 12.10.2010
Сообщений: 25

запрос на связь таблиц.

Добрый день.
Есть следующая проблема.
Есть база данных с новостями к новостям(news) прикреплены фотографии (linkNews2Pic), видео (linkNews2Video) и публикации (linkNews2Smi). Необходимо вывести все новости и для каждой новости количество прикрепленных фотографий видео и публикаций.

Упрощенная структура БД
CREATE TABLE IF NOT EXISTS `news` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);
INSERT INTO `rus_smartix_news_new` (`id`, `name`) VALUES (1, 'first'),(2, 'second'), (3, 'third');

CREATE TABLE IF NOT EXISTS `linkNews2Pic` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `newsId` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
);
INSERT INTO `linkNews2Pic` (`id`, `newsId`) VALUES (1, 1), (2, 1), (3, 3), (5, 3);

CREATE TABLE IF NOT EXISTS `linkNews2Video` (
  `newsId` int(10) unsigned NOT NULL,
  `videoId` int(10) unsigned NOT NULL,
  PRIMARY KEY (`newsId`,`videoId`)
);
INSERT INTO `linkNews2Video` (`newsId`, `videoId`) VALUES (1, 561), (1, 563), (1, 564), (2, 556), (3, 563), (3, 565);

CREATE TABLE IF NOT EXISTS `linkNews2Smi` (
  `newsId` int(10) unsigned NOT NULL,
  `smiId` int(10) unsigned NOT NULL,
  PRIMARY KEY (`newsId`,`smiId`)
);
INSERT INTO `linkNews2Smi` (`newsId`, `smiId`) VALUES (1, 3), (1, 4);


Все что приходило в голову работало только если связывать новость только с фотографиями. В этом случае работало замечательно через
SELECT n.name, count(p.id) photoNum
FROM `new` n
LEFT JOIN linkNews2Pic p ON p.newsId = n.id
GROUP BY n.id
но при добавлении еще join-ов - данные получаются неверными. Почему получается не так - понимаю, но вот как исправить - не пойму. Подскажите пожалуйста
Для проверки должно возвращать
first     2 3 2
second 0 1 0
third    2 2 1

Неактивен

 

#2 26.01.2011 17:50:31

Altukhov
Участник
Зарегистрирован: 25.01.2011
Сообщений: 9

Re: запрос на связь таблиц.

напишите в лефтджойне не название таблицы, а селект с количество видео/фото/новостей примерно так
LEFT JOIN (SELECT newsId, count(videoId) FROM `linkNews2Video` GROUP BY newsId) t ON t.newsId = n.id

и так еще два джойна. должно заработать

Отредактированно Altukhov (26.01.2011 17:52:05)

Неактивен

 

#3 26.01.2011 18:05:15

nikolajtesla
Завсегдатай
Зарегистрирован: 12.10.2010
Сообщений: 25

Re: запрос на связь таблиц.

Спасибо большое. Хотелось бы узнать или это единственный способ?

Неактивен

 

#4 26.01.2011 18:18:54

Altukhov
Участник
Зарегистрирован: 25.01.2011
Сообщений: 9

Re: запрос на связь таблиц.

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

select n.num, v1.video, p1.pict, s1.smi from news n,
(select v.id,count(v.video) as video from video v group by v.id) v1,
(select p.id,count(p.pict) as pict from pict p group by p.id) p1,
(select s.id,count(s.smi) as smi from smi s group by s.id) s1
where n.id = v1.id
and n.id = p1.id
and n.id = s1.id

Неактивен

 

#5 26.01.2011 19:24:18

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: запрос на связь таблиц.

Последний вариант мне нравится больше. Левые объединения не стоит
использовать там, где они не нужны.

Но я бы пошел еще дальше, и не считал бы большие вложенные запросы,
а заменил бы их на коротенькие:
SELECT n.*, (SELECT COUNT(*) FROM video WHERE newsID = n.id) AS video_count, ...
FROM news n;

Неактивен

 

#6 27.01.2011 09:59:28

Altukhov
Участник
Зарегистрирован: 25.01.2011
Сообщений: 9

Re: запрос на связь таблиц.

А можно пойти еще дальше и сделать так big_smile

select n.num, count( distinct v.video), count(distinct p.pict),  count(distinct s.smi)
from news n, video v, pict p, smi s
where n.id = v.id
and n.id = p.id
and n.id = s.id
group by n.num

не знаю как в мускуле, но в оракле работает

Неактивен

 

#7 28.01.2011 01:35:48

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: запрос на связь таблиц.

Должно работать, да. А вот как обработается DISTINCT — не знаю.
COUNT(*) по индексу просто посчитает количество дочерних эле-
ментов в индексе, а DISTINCT вполне таки может вытащить все, а
потом посортировать. Но способ красивый и понятный, мне нравится smile

Неактивен

 

#8 28.01.2011 12:56:24

nikolajtesla
Завсегдатай
Зарегистрирован: 12.10.2010
Сообщений: 25

Re: запрос на связь таблиц.

Огромное всем спасибо

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson