MySql:使用联合或连接按计数选择
Posted
技术标签:
【中文标题】MySql:使用联合或连接按计数选择【英文标题】:MySql: Select by Count with Union or Joins 【发布时间】:2011-12-16 19:26:38 【问题描述】:我需要一种方法让页面管理员查看他们页面的成员,这些成员按用户在该特定页面上的帖子总数排序。帖子存储在不同的表格中,例如投票、下载、wiki 等(如 15 个表格)。每个都有 id、user_id、page_id、title、content 等结构。列出页面所有用户的表称为“收藏夹”。它的结构就是 id, user_id, page_id, date。
我目前有一个查询,它将所有“内容表”联合在一起,以便特定用户在网站上显示他们关于它所在页面的所有帖子,我可以很容易地使用 WHERE 使其特定于每个页面page_id = $page_id)。我尝试使用该代码来执行我在版主区域中尝试执行的操作。正如我所提到的,在版主区域中,我需要按用户的总帖子数 DESC 对用户列表进行排序。
我有这个代码,但它不工作。
$getfans = mysql_query("SELECT DISTINCT user_id, ((SELECT id FROM wiki WHERE wiki.page_id = $page_id AND wiki.user_id = favorites.user_id)
UNION ALL
(SELECT id FROM downloads WHERE downloads.page_id = $page_id AND downloads.user_id = favorites.user_id)
UNION ALL
(SELECT id FROM polls WHERE polls.page_id = $page_id AND polls.user_id = favorites.user_id)) AS posts
FROM favorites WHERE favorites.page_id = $page_id AND favorites.status = 0 ORDER BY posts DESC", $conn);
我尝试了其他同样无效的方法,但这个方法对我来说最合乎逻辑,所以我将只展示它
请帮忙。谢谢。
另外...
这也许是朝着正确方向迈出的一步
$getfans = mysql_query("SELECT DISTINCT user_id, (SELECT COUNT(id) FROM polls WHERE page_id = $page_id AND user_id = favorites.user_id) AS 来自收藏夹的帖子 WHERE favorites.page_id = $page_id AND favorites.status = 0 ORDER BY posts DESC", $conn);
当我回显 $posts 时,它为我提供了该页面用户投票的正确计数。
但是,当我尝试处理多个表时,它只返回了一个用户。
例子:
$getfans = mysql_query("SELECT DISTINCT user_id, SUM((SELECT COUNT(id) FROM polls WHERE page_id = $page_id AND user_id = favorites.user_id)+(SELECT COUNT(id) FROM wiki WHERE page_id = $page_id AND user_id = favorites.user_id)) 来自收藏夹的帖子 WHERE favorites.page_id = $page_id AND favorites.status = 0 ORDER BY 发布 DESC", $conn);
我找到了解决方案 如果好奇,请阅读我下面的帖子。
【问题讨论】:
你是在总结每个用户每个表中有多少行吗? 是的。而且我已经完成了各种方法,包括 COUNT(*) 和 * 但仍然没有奏效。当我只是想显示一个用户的所有帖子时,整个联合块本身就可以工作,但当我试图显示所有用户然后按帖子排序时却不行。 【参考方案1】:使用左连接!
SELECT
f.user_id,
COUNT(w.user_id) + COUNT(d.user_id) + COUNT(p.user_id) as PageCount
FROM
favorites f
left join wiki w on
f.page_id = w.page_id
and f.user_id = w.user_id
left join downloads d on
f.page_id = d.page_id
and f.user_id = d.user_id
left join polls p on
f.page_id = p.page_id
and f.user_id = p.user_id
WHERE
f.page_id = $page_id
AND f.status = 0
GROUP BY
f.user_id
ORDER BY PageCount DESC
如果您想坚持联合方法:
select
f.user_id,
count(x.user_id) as PageCount
from
favorites f
inner join (
select user_id, page_id from wiki
union all
select user_id, page_id from downloads
union all
select user_id, page_id from polls
union all
select user_id, page_id from videos
) x on
f.user_id = x.user_id
and f.page_id = x.page_id
WHERE
f.page_id = $page_id
AND f.status = 0
group by
f.user_id
ORDER BY PageCount DESC
您想将group by
用于聚合,而count
函数将忽略您遇到的任何空值,因此它仅计算正匹配。
【讨论】:
嗯,我不确定这是否会令人愉快,因为我所拥有的表格不仅是我示例中的三个(民意调查、维基和下载),还有……视频、照片、演练、维基、评论、文章、新闻、争议、forums_posts、报价、测验……也许还有一些我错过的。我不明白我是否可以使用一个大型联合来计算所有这些,以便用户查看他们所有帖子的长列表,为什么我不能使用相同的计数来为他们的帖子排序? 添加了联合方法。不知道 MySQL,但 SQL Server 通常会优化这些谓词,因此您不会拉回很多东西。无论如何,您实际上不会看到左连接实例中的表,您只会使用它们来过滤您的查询。您将看到的唯一内容是您在子句的select
部分中拉回的列。
另外,我刚刚尝试了您的代码,但没有成功。我还将 PageCount 更改为帖子,以查看是否是问题所在,但这也不起作用。
“没用”是什么意思?你期待看到什么结果却没有看到?还是您收到错误消息?您尝试了哪个代码——第一个还是第二个?
AHHHHHHHH :) 只有一个变化。我不得不将 INNER JOIN 更改为 LEFT JOIN,因为我需要它来显示页面的所有用户,即使是那些有 0 个帖子的用户,而之前(使用内部连接)它只显示在其他表中有行的用户。感谢SSSSSSSS【参考方案2】:
我找到了解决方案。我以为我早点有这个,但我想我有点偏离了。感谢所有参与的人。
$getfans = mysql_query("SELECT DISTINCT user_id,
(SELECT COUNT(id) FROM wiki WHERE page_id = $page_id AND user_id = favorites.user_id) +
(SELECT COUNT(id) FROM downloads WHERE page_id = $page_id AND user_id = favorites.user_id) +
(SELECT COUNT(id) FROM polls WHERE page_id = $page_id AND user_id = favorites.user_id)
AS posts FROM favorites
WHERE favorites.page_id = $page_id
AND favorites.status = 0
ORDER BY posts DESC", $conn);
只需继续在每个新表的末尾使用 + 进行子查询。也许不是最简洁的代码,但它确实有效。
这行得通。这两天我不能接受它作为答案:(
【讨论】:
删除DISTINCT
并在ORDER BY
之前添加GROUP BY user_id
是的,GROUP BY
会比 DISTINCT
快(但首先要检查它们是否产生相同的结果,我认为在这种情况下它们会这样做)。【参考方案3】:
这是我最喜欢的一个表的 SQL 查询,
Select Distinct user_id, Count(user_id) as C from yourtable group by user_id
将向您显示每个人的 user_id 以及他们在该表中的行数。组合这些结果应该很简单。
顺便说一句,如果所有表都具有相同的结构,为什么不将它们都放在同一个表中?您可以添加一列来指示记录适用于哪种类型的项目。
【讨论】:
那样会非常混乱,因为结构不完全相同。 ...我不确定你写的内容将如何应用于我在示例中给出的 3 个表。你能进一步解释一下吗?在您的示例中实际使用我的表格? 我对你投了反对票有两个原因:(1) 当你有一个group by
时,你使用了一个不必要的distinct
,(2) 你只展示了一个通用聚合而不是帮助用户解决他或她的问题。
不同的可能是我的错,因为我一直在尝试一切(有点像在这里拉稻草),有时当我继续我的下一次尝试时,有些事情在我的查询中徘徊不应该一直待在那里,直到我意识到并把它拿出来再试一次。他只是复制和粘贴。至于没有帮助,我同意。
你知道,埃里克,我多年来一直在使用该查询。我不确定是否需要 distinct。以上是关于MySql:使用联合或连接按计数选择的主要内容,如果未能解决你的问题,请参考以下文章