我正在建立一个网站,用户可以在该网站上提交截屏视频并与它们相关联,标签。
这是构成数据库的 3 个表:
Screencasts:
| screencastId | title |
|--------------|--------------------------------------------------|
| CF9S4QZuV30 | Go Programming |
| ef-6NZjBtW0 | How to Make Android Apps |
| F3WpBsc0QEw | Git & GitHub: Creating a Repository (2/11) |
| Ggh_y-33Eso | Learn HTML in 15 Minutes |
| GrycH6F-ksY | jQuery Tutorials: Submitting a Form with AJAX |
| N4mEzFDjqtA | Python Programming |
| QRmmISj6Rrw | Learn PHP: Your first file |
| WPvGqX-TXP0 | Java Programming |
| wz3kElLbEHE | SASS Tutorial |
| Xx-XZwJT76w | Setting Up A Development Environment With Bowery |
Tags:
| tagName |
|---------|
| Android |
| Bowery |
| Git |
| Go |
| Html |
| Java |
| jQuery |
| PHP |
| Python |
| Sass |
ScreencastTags
| screencastId | tagName |
|--------------|---------|
| CF9S4QZuV30 | Go |
| ef-6NZjBtW0 | Android |
| ef-6NZjBtW0 | Java |
| F3WpBsc0QEw | Git |
| Ggh_y-33Eso | Html |
| GrycH6F-ksY | jQuery |
| N4mEzFDjqtA | Python |
| QRmmISj6Rrw | PHP |
| WPvGqX-TXP0 | Java |
| wz3kElLbEHE | Sass |
| Xx-XZwJT76w | Bowery |
该网站允许用户查看 9 最流行的标签:
我用来确定这 9 个最受欢迎的标签的查询如下:
SELECT t.tagName
FROM tags t
JOIN screencastTags m
ON m.tagName = t.tagName
GROUP BY t.tagName
ORDER BY COUNT(*) DESC, t.tagName DESC
LIMIT 9
如您所见,有一个名为其他 的第10 菜单项。单击后,用户会看到其标签不在 9 个最流行的标签中的截屏视频。
我用来确定这些截屏视频的查询如下:
SELECT
v.screencastId,
v.title,
GROUP_CONCAT(m.tagName) as tags
FROM screencasts v
JOIN screencastTags m
ON v.screencastId = m.screencastId
WHERE m.tagName NOT IN (
SELECT * FROM (
SELECT t.tagName
FROM tags t
JOIN screencastTags m
ON m.tagName = t.tagName
GROUP BY t.tagName
ORDER BY COUNT(*) DESC, t.tagName DESC
LIMIT 9) as t)
GROUP BY v.screencastId
ORDER BY v.ReferralCount DESC
不幸的是,这个查询确实如我所愿。结果如下表:
| screencastId | title | tagName |
|--------------|--------------------------|---------|
| ef-6NZjBtW0 | How to Make Android Apps | Android |
我希望它返回这张表:
| screencastId | title | tagName |
|--------------|--------------------------|---------------|
| ef-6NZjBtW0 | How to Make Android Apps | Android, Java |
在这种情况下,如何达到预期的结果?
如您所见,子查询返回了 9 个最流行的标签,其中包括 Java 标签。因为查询返回的截屏视频的标签在子查询结果中是not,所以不包括标签Java。应该是,因为截屏视频被标记为 Android 和 Java。 Android 不是 9 个最流行的标签之一,Java 是。
最佳答案
如果你想要截屏不包含这 9 个标签,那么逻辑更像这样:
SELECT v.screencastId, v.title,
GROUP_CONCAT(m.tagName) as tags
FROM screencasts v JOIN
screencastTags m
ON v.screencastId = m.screencastId LEFT JOIN
(SELECT t.tagName
FROM tags t JOIN
screencastTags m
ON m.tagName = t.tagName
GROUP BY t.tagName
ORDER BY COUNT(*) DESC, t.tagName DESC
LIMIT 9
) tags9
ON m.tagname = tags9.tagname
GROUP BY v.screencastId, v.title
HAVING SUM(tags9.tagname IS NOT NULL) = 0;
这是在做什么? LEFT JOIN
将标签与九个原始标签匹配(假设数据库在两次查询之间没有更新)。聚合是由屏壳。 HAVING
子句然后检查是否与九个标记不匹配。这保证了九个标签中没有一个是该查询的返回值。
编辑:
糟糕,我想我误解了这个问题。我以为您想要没有九个标签的截屏。相反,您需要所有带有附加标签的屏幕转换标签。
这实际上是上述查询的一个小变体。这不是检查所有 标签是否不同,而是检查任何 标签是否不同。唯一的变化是 HAVING
子句:
SELECT v.screencastId, v.title,
GROUP_CONCAT(m.tagName) as tags
FROM screencasts v JOIN
screencastTags m
ON v.screencastId = m.screencastId LEFT JOIN
(SELECT t.tagName
FROM tags t JOIN
screencastTags m
ON m.tagName = t.tagName
GROUP BY t.tagName
ORDER BY COUNT(*) DESC, t.tagName DESC
LIMIT 9
) tags9
ON m.tagname = tags9.tagname
GROUP BY v.screencastId, v.title
HAVING SUM(tags9.tagname IS NULL) > 0;
关于mysql - 如何向查找最流行记录的查询添加异常(exception)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30141267/