我有三个mysql表,我想从中提取一些信息,表格是:
我想要做的是找到每个标签得分最高的视频。有许多视频具有相同的标签,但我的结果集将具有 与标签相同的行数。最终目标是为每个唯一标记设置一个最佳视频列表(按点数)(标签是以哈希为前缀的主题)。
我的SQL noob尝试实现此目的如下:
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
不幸的是,第二行的video_id不是我所期望的,因为owner-y-video-l 没有44分,而是有17分,所以不会是得分最高的视频 ID为222的标记。
任何可以帮助我的SQL Universe大师?万分感谢:)。
答案 0 :(得分: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 :(得分: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