2013-10-14 3 views
5

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

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

К сожалению, появляется несколько совпадений :(Чувство моего чувства заключается в том, что запрос соответствует видеоизображению для каждого соединения и выплевывает двойное вверх (как вы увидите в связанной скрипте, но учитывая, что моя общая сумма SQL Присоединитесь к опыту примерно с 3 часов назад. Мне до сих пор удалось запутать OK, но теперь можно сделать несколько советов о том, куда идти дальше.

Ниже приведена схема и запрос. была борьба с, а вот это sqlfiddle ссылка,

Схема:

create table videos 
(
    videoId int(1) AUTO_INCREMENT, 
    videoUUID char(40), 
    contentFolder varchar(50), 
    title varchar(50), 
    caption varchar(50), 
    duration varchar(15), 
    date TIMESTAMP, 
    url varchar(55), 
    text varchar(250), 
    PRIMARY KEY (videoId) 
); 

create table tags 
( 
    tagId int(1) AUTO_INCREMENT, 
    tagName varchar(15), 
    PRIMARY KEY (tagId) 
); 

create table channels 
(
    channelId int(1) AUTO_INCREMENT, 
    channelName varchar(15), 
    PRIMARY KEY (channelId) 
); 

create table videoTags 
(
    videoTagId int(1) AUTO_INCREMENT, 
    videoId int(1), 
    tagId int(1), 
    PRIMARY KEY (videoTagId) 
); 

create table videoChannels 
(
    videoChannelId int(1) AUTO_INCREMENT, 
    videoId int (1), 
    channelId int (1), 
    PRIMARY KEY (videoChannelId) 
); 

// 
create trigger tuuid before insert on videos 
for each row begin 
set new.videoUUID = uuid(); 
end// 

insert into videos 
    (contentFolder, title,caption,duration,url,text) 
values ("someDir/","A Movie Title", "Headline for Movie", 
    "00:05:11", 
    "http://someserver.ip/somedir/test.mp4", 
    "Some text as part of the video file description here"); 

insert into tags (tagName) values 
('Flowers'),('Dogs'),('Cats'),('YaMum'),('orlyowl'); 

insert into channels (channelName) values 
('General'), ('NotSoGeneral'), ('Specific'), ('Broad'), ('Narrow'), 
('Obsolete'); 

insert into videoTags (videoId,tagId) values 
(1,2),(1,5); 

insert into videoChannels (videoId,channelId) values 
(1,1),(1,4),(1,6); 

Запрос:

select distinct v.*,group_concat(t.tagName)Tags, 
group_concat(c.channelName)Channels 
from videos as v 

inner join videoTags as vt on v.videoId = vt.videoid 

inner join tags as t on t.tagId = vt.tagId 

inner join videoChannels as vc on v.videoId = vc.videoId 

inner join channels as c on c.channelId = vc.channelId 

group by v.videoId; 

Am Я буду об этом правильно? Есть ли только фундаментальная ошибка в том, как я структурировал запрос, который это делает? Или схема неправильна для того, что я пытаюсь выполнить.

Любая помощь была бы принята с благодарностью!

@J Lo Спасибо за ответ!

Ответ: отчетливое Ключевое слово, я попробовал его в отборного заявления, но не был уверен, как его использование так не в полной мере оценить, где она может быть использована, @J Lo так лаконично указал, я могу использовать его в моей GROUP_CONCAT, таким образом давая запрос:

select v.*,group_concat(distinct t.tagName)Tags, 
group_concat(distinct c.channelName)Channels 
from videos as v 

inner join videoTags as vt on v.videoId = vt.videoid 

inner join tags as t on t.tagId = vt.tagId 

inner join videoChannels as vc on v.videoId = vc.videoId 

inner join channels as c on c.channelId = vc.channelId 

group by v.videoId; 
+0

Это MySQL правильно? В этом случае вы не должны использовать тег sql-server. Но спасибо за то, что вы подготовили свой вопрос так хорошо. – Szymon

+1

Cheers mate, я просто пошел с предлагаемыми тегами, должен был прочитать их немного ближе. – splintex

ответ

3

Вашей первой пара присоединяется (Video/VideoTags/Теги) приводит таблицу, как так:

VideoID = 1 will bring in TagID = 2,5 (Dogs, orlyowl) so you have this 

| 1 | Dogs 
| 1 | orlyowl 

Когда вы присоединяетесь к VideoChannels, он дублируетВышеуказанные записи для каждого канала

| 1 | Dogs | 1 
| 1 | orlyowl | 1 
| 1 | Dogs | 4 
| 1 | orlyowl | 4 
| 1 | Dogs | 6 
| 1 | orlyowl | 6 

GROUP_CONCAT имеет DISTINCT атрибут

select v.* 
    , group_concat(distinct t.tagName) Tags 
    , group_concat(distinct c.channelName) Channels 
from videos as v 
inner join videoTags as vt on v.videoId = vt.videoid 
inner join tags as t on t.tagId = vt.tagId 
inner join videoChannels as vc on v.videoId = vc.videoId 
inner join channels as c on c.channelId = vc.channelId 
group by v.videoId; 
+0

Я хотел, чтобы группа TAGS и группа CHANNELS отображались в наборе результатов ** [ЗДЕСЬ] (http://www.sqlfiddle.com/#!2/765385/1/0) **, но без двойных взлетов, которые происходят. Наверное, я только смутился в своей голове, как должны работать соединения. Я хочу получить все ** TAGS **, связанные с определенным видеофайлом, а также все ** CHANNELS **, в которые он входит. Ссылка SQLFiddle даст вам в значительной степени то, что я хочу, чтобы оно выглядело. Спасибо что нашли время ответить. – splintex

+0

@J Lo Спасибо! Лес для деревьев, я думаю, я пробовал DISTINCT, но не в том месте. Должен прочитать немного больше о его использовании. Сортировал меня в коротком порядке, и снова, большое спасибо. – splintex

Смежные вопросы