2013-10-14 4 views
5

いくつかのテーブル間で内部結合を行うと、冗長性を捨てるクエリにいくつかの問題があります。SQL多重テーブル結合ダブルを投げる

本質的に、videoIdに基づいていくつかのタグとチャンネル(ジャンルを考えてください)に参加しているので、特定のビデオファイルは複数のタグを持ち、複数のチャンネルの一部になることがあります。

残念なことに、複数のマッチが表示されます:(私の直感は、クエリがそれぞれの結合に対してvideoIdと一致していることです(リンクされたフィドルに表示されますが、参加の経験は約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; 

は、私がこれについて正しい道を行くのですか?私はこれを行うクエリを構造化した方法について基本的な間違っているだけですか?または、私が達成しようとしていることに対してスキーマが間違っています。

ご協力いただければ幸いです!

@J Lo答えに感謝します!

回答: DISTINCTキーワード、それを使用することができるところ、私はselect文でそれを試してみましたが、その使用方法についての不明な点だったので、完全には感謝していなかった、@Jローので簡潔に私ができる、指摘したがって、クエリを与え、私の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

DISTINCT属性を持っていますか?この場合、sql-serverタグは使用しないでください。しかし、あなたの質問をとてもうまく準備してくれてありがとう。 – Szymon

+1

仲間たち、私はちょうど提案されたタグと一緒に行きました、それらをもう少し詳しく読むべきです。 – splintex

答えて

3

あなたの最初のカップルは、(ビデオ/ 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のための上記のエントリは、これはmysqlの権利がある

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)**に表示されました**しかし、ダブルアップなし起こっている。私はちょうど結合がどのように働くはずであるか私の頭の中で混乱してきたと思います。特定の動画ファイルに関連付けられている**すべての**タグ**と、それが含まれているすべての**チャンネル**を取得したいと思います。 SQLFiddleのリンクは、私がそれを見たいものをあなたに与えるでしょう。答える時間をとってくれてありがとう。 – splintex

+0

@J Loありがとう!私は思った木の森、私はDISTINCTを試みたが、間違った場所に。その使用方法についてもう少し読んでいるはずです。短い順序で私を並べ替え、また、多くのありがとう。 – splintex