我正在尝试查找特定用户拥有的视频点数。
以下是三个相关的表格:
CREATE TABLE `userprofile_userprofile` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`full_name` varchar(100) NOT NULL,
...
)
CREATE TABLE `userprofile_videoinfo` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`title` varchar(256) NOT NULL,
`uploaded_by_id` int(11) NOT NULL,
...
KEY `userprofile_videoinfo_e43a31e7` (`uploaded_by_id`),
CONSTRAINT `uploaded_by_id_refs_id_492ba9396be0968c` FOREIGN KEY (`uploaded_by_id`) REFERENCES `userprofile_userprofile` (`id`)
)
CREATE TABLE `userprofile_videocredit` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`video_id` int(11) NOT NULL,
`profile_id` int(11) DEFAULT NULL,
KEY `userprofile_videocredit_fa26288c` (`video_id`),
KEY `userprofile_videocredit_141c6eec` (`profile_id`),
CONSTRAINT `profile_id_refs_id_31fc4a6405dffd9f` FOREIGN KEY (`profile_id`) REFERENCES `userprofile_userprofile` (`id`),
CONSTRAINT `video_id_refs_id_4dcff2eeed362a80` FOREIGN KEY (`video_id`) REFERENCES `userprofile_videoinfo` (`id`)
)
videoinfo
表是用户上传视频时,他会获得“uploaded_by”列表。 videocredit
表是给定电影的所有积分。它完全独立于上传电影(即,视频可以由用户上传而无需记入自己,并且用户可以记入他未上传的视频中。)
在尝试查找用户已被记入的COUNT个视频时,我想找到:
# videos a user has uploaded + # of non duplicate-video credits uploaded by others
举例来说:如果用户上传了5个视频:
VideoME1, VideoME2, VideoME3, VideoME4, and VideoME5
(total = 5 videos [`videoinfo.uploaded_by_id`])
并有以下视频信用:
VideoME1 (4 credits - director, writer, editor, choreographer)
VideoME2 (1 credit)
VideoOTHER1 (2 credits - writer, editor)
VideoOTHER2 (1 credit - writer)
(total = 8 video credits [`videocredit.profile_id`])
COUNT应为5(视频已上传)+ 2(其他人上传的非重复视频片段)= 7.如果用户没有视频片段,则应为= 0(即LEFT OUTER JOIN
)。< / p>
我已经能够找出每个上传/信用的COUNTS,但无法弄清楚如何将两者结合起来并摆脱重复。我需要做什么SQL?谢谢。
顺便说一句,这就是我目前为每个(个人)COUNT所拥有的:
mysql> SELECT full_name, v.video_id, COUNT(DISTINCT v.video_id) as cnt
-> FROM userprofile_userprofile u LEFT OUTER JOIN userprofile_videocredit v
-> ON u.id = V.profile_id
-> GROUP BY full_name
-> ORDER BY cnt DESC;
mysql> SELECT full_name, v.id, COUNT(v.uploaded_by_id) as cnt
-> FROM userprofile_userprofile u LEFT OUTER JOIN userprofile_videoinfo v
-> ON u.id = v.uploaded_by_id
-> GROUP BY full_name
-> ORDER BY cnt DESC;
答案 0 :(得分:2)
X-Zero建议在数据中添加“上传者信用”是保持查询简单的最佳方法。如果这不是一个选项,请在userprofile_videoinfo和userprofile_videocredit之间进行内部联接,以便轻松消除重复项:
SELECT u.id, u.full_name, COUNT(DISTINCT v.video_id) as credit_count
FROM userprofile_userprofile u
LEFT JOIN (SELECT vi.video_id, vi.uploaded_by_id, vc.profile_id as credited_to_id
FROM userprofile_videoinfo vi
JOIN userprofile_videocredit vc ON vi.id = vc.video_id
) v ON u.id = v.uploaded_by_id OR u.id = v.credited_to_id
GROUP BY u.id, u.full_name
ORDER BY credit_count DESC
子查询可能对创建视图很有用。
答案 1 :(得分:1)
基本上有两种方法可以做到这一点:
1)添加'上传者'作为他们可以记入的东西,并添加一个触发器来自动填充该条目 - 只有一个表格,等等。
2)我相信以下查询也应该有效(这也将解决您的full_name
问题):
WITH credit_rollup (profile_id) as (SELECT profile_id
FROM userprofile_videocredit
GROUP BY profile_id, video_id)
SELECT full_name, COALESCE((SELECT count(*)
FROM credit_rollup as v
WHERE v.profile_id = u.id), 0) +
COALESCE((SELECT count(*)
FROM userprofile_videoinfo as v
WHERE v.uploaded_by_id = u.id), 0) as credits
FROM userprofile_userprofile
ORDER by credits DESC
尽管如此,您可能希望从每个表名前面删除“userprofile”,然后将它们放在具有该名称的模式中。
编辑查询只能为每个视频计算1个点数。
在再次审阅该帖子后,很明显我错过了“重复”这个词的关键用法 - 因为用户只上传了一次视频并在视频中获得某种信用(导演,编辑等),但不是两次(这是一个OR) 因此,以下查询更符合要求(感谢@simon让我考虑一下):
WITH credit_rollup (uploaded_by_id, credited_to_id)
AS (SELECT info.uploaded_by_id, credit.profile_id
FROM userprofile_videoinfo as info
JOIN userprofile_videocredit as credit
ON info.id = credit.video_id
GROUP BY info.uploaded_by_id, credit.profile_id)
SELECT usr.full_name, COALSECE((SELECT count(*)
FROM credit_rollup as rollup
WHERE rollup.uploaded_by_id = usr.id
OR rollup.credited_to_id = usr.id), 0) as credits
FROM userprofile as usr
ORDER BY credits DESC
正如@simon说的那样,CTE(他使用子查询)可能有助于创建一个视图(基本上,它列出了每个人曾经为他们在视频中的参与,一个方便的事情)。
答案 2 :(得分:0)
如果我没有犯错:
SELECT u.id
, u.full_name
, ( SELECT COUNT(*)
FROM userprofile_videoinfo vi
WHERE u.id = vi.uploaded_by_id
) AS cnt_VideosUploadedBy <---- 5
, cnt_Credits_InMyUploads
+ cnt_Videos_CreditedIn - cnt_Videos_CreditedIn_and_UploadBy
AS cnt_Difficult <---- 5 + 4 - 2 = 7
, cnt_Credits_Total <---- 8
, cnt_Credits_InMyUploads <---- 5
, cnt_Videos_CreditedIn <---- 4
, cnt_Videos_CreditedIn_and_UploadBy <---- 2
FROM userprofile_userprofile u
LEFT JOIN
( SELECT u.id
, COUNT(vc.video_id)
AS cnt_Credits_Total
, (COUNT(vi.profile)
AS cnt_Credits_InMyUploads
, COUNT(DISTINCT vc.video_id)
AS cnt_Videos_CreditedIn
, (COUNT(DISTINCT vi.id)
AS cnt_Videos_CreditedIn_and_UploadBy
FROM userprofile_userprofile u
JOIN userprofile_videocredit vc
ON u.id = vc.profile_by_id
LEFT JOIN userprofile_videoinfo vi
ON vc.video_id = vi.id
AND vi.profile = u.id
GROUP BY u.id
) AS grp
ON grp.id = u.id