2

いくつかの情報を抽出したい mysql テーブルが 3 つあります。テーブルは次のとおりです。

  • ビデオ - スコア付きのビデオを表します。
  • タグ - タグのグローバル リストが含まれます。
  • VideoTags は、ビデオとタグの間の関連付けを作成します。

私がやりたいのは、各タグのポイントが最も高い動画を見つけることです。同じタグを持つ動画は多数ありますが、結果セットにはタグと同じ数の行が含まれます。最終的な目標は、一意のタグ (ハッシュの前に付けられたトピックであるタグ) ごとに (ポイントによる) 最高のビデオのリストを作成することです。

これを達成するための私のSQL初心者の試みは次のとおりです。

  SELECT video.id AS video_id, video.owner_id, MAX(video.points), tag.id AS tag_id
    FROM Videos video, VideoTags videotag, Tags tag
   WHERE video.id = videotag.video_id
     AND videotag.tag_id = tag.id
     AND tag.content LIKE '#%'
GROUP BY tag.id

スキーマとサンプル データは次のとおりです。

DROP TABLE IF EXISTS `Video`;
CREATE TABLE `Video` (
  `id` varchar(24) NOT NULL default '',
  `owner_id` varchar(24) NOT NULL default '',
  `points` DOUBLE NOT NULL default 0
);

DROP TABLE IF EXISTS `Tags`;
CREATE TABLE `Tags` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `content` varchar(32) NOT NULL default ''
PRIMARY KEY (id)
);

DROP TABLE IF EXISTS `VideoTags`;
CREATE TABLE `VideoTags` (
  `video_id` varchar(24) NOT NULL default '',
  `tag_id` int(11) NOT NULL
);

INSERT INTO Videos (id,owner_id,points) VALUES ('owner-x-video-a','owner-x', 20);
INSERT INTO Videos (id,owner_id,points) VALUES ('owner-x-video-b','owner-x', 15);
INSERT INTO Videos (id,owner_id,points) VALUES ('owner-y-video-k','owner-y', 12);
INSERT INTO Videos (id,owner_id,points) VALUES ('owner-y-video-l','owner-y', 17);
INSERT INTO Videos (id,owner_id,points) VALUES ('owner-y-video-m','owner-y', 44);

INSERT INTO Tags (id, content) VALUES (111, '#topic-1');
INSERT INTO Tags (id, content) VALUES (222, '#topic-2');

INSERT INTO VideoTags (video_id,tag_id) VALUES ('owner-x-video-a',111);
INSERT INTO VideoTags (video_id,tag_id) VALUES ('owner-x-video-b',111);
INSERT INTO VideoTags (video_id,tag_id) VALUES ('owner-y-video-k',111);
INSERT INTO VideoTags (video_id,tag_id) VALUES ('owner-y-video-l',222);
INSERT INTO VideoTags (video_id,tag_id) VALUES ('owner-y-video-m',222);

私が期待しているのは次のとおりです。

video_id          owner_id    MAX(video.points)  tag_id
owner-x-video-a   owner-x     20                 111
owner-y-video-m   owner-y     44                 222

しかし、私が得るものは:

video_id          owner_id    MAX(video.points)  tag_id
owner-x-video-a   owner-x     20                 111
owner-y-video-l   owner-y     44                 222

残念ながら、2 行目の video_id は期待したものではありません。owner-y-video-l には 44 ポイントがなく、むしろ 17 ポイントであるため、ID 222 のタグの最高得点の動画にはなりません。

私を助けることができるSQLユニバースのマスターはいますか? どうもありがとう :)

4

2 に答える 2

2

グループごとの最大値が必要です:

SELECT * FROM Video JOIN (

  SELECT   VideoTags.tag_id, MAX(points) points
  FROM     Video JOIN VideoTags ON Video.id = VideoTags.video_id
  GROUP BY VideoTags.tag_id

) t USING (points) JOIN Tags ON t.tag_id = Tags.id

sqlfiddleで参照してください。

このクエリは、各タグ内の最大ポイント数を持つすべてのビデオを返すため、関連付けられたタグに対して複数のレコードが返されることに注意してください。このような状況で 1 つのレコードのみを返却する場合は、返却するビデオを決定する方法を指定してください。

于 2012-10-08T09:14:52.273 に答える
0
In your query 

SELECT video.id AS video_id, video.owner_id, MAX(video.points), tag.id AS tag_id
    FROM Videos video, VideoTags videotag, Tags tag
   WHERE video.id = videotag.video_id
     AND videotag.tag_id = tag.id
     AND tag.content LIKE '#%'
GROUP BY tag.id

"videotag.tag_id = tag.id" this will have two row matching so it override the 2nd value 

INSERT INTO Tags (id, content) VALUES (222, '#topic-2');

INSERT INTO VideoTags (video_id,tag_id) VALUES ('owner-y-video-l',222);
INSERT INTO VideoTags (video_id,tag_id) VALUES ('owner-y-video-m',222);

which show the wrong result.

So if we try it to group by using "videotag.tag_id" than it will show the right result.

SELECT video.id AS video_id, video.owner_id, MAX(video.points), tag.id AS tag_id
    FROM Videos video, VideoTags videotag, Tags tag
   WHERE video.id = videotag.video_id
     AND videotag.tag_id = tag.id
     AND tag.content LIKE '#%'
GROUP BY videotag.tag_id
于 2012-10-08T09:24:33.640 に答える