可以比较MySQL上多行的COUNT(*)吗?

时间:2009-05-15 14:37:52

标签: mysql

您好我正在使用以下架构查询用户查看公司搜索的频率(该应用程序基本上允许您按公司进行搜索)

SEARCH_LOG
----------
date_of_search (DATETIME)
company_id (INT)


COMPANIES
---------
id (INT)
company_name (VARCHAR)

(there are more columns but these are the relevant ones)

所以我正在运行以下查询:

SELECT company_name,COUNT(*) FROM companies LEFT OUTER JOIN search_log ON search_log.company_id=companies.id GROUP BY companies.id

这很棒,因为它会返回每个公司和执行的搜索次数,但我想将这些数字表示为百分比。我的膝跳反应是单独运行以下查询:

SELECT COUNT(*) FROM search_log

获取结果并在应用程序端进行划分,但这看起来效率非常低,如果可能的话我想在一个查询中完成所有操作(最好不使用子查询)但不知道如何得到那些信息。

任何帮助或指导都将不胜感激。

编辑:也许我并不完全清楚我追求的是什么。而不是得到如下结果:

COMPANY_NAME | COUNT(*)
-----------------------
CompanyA     | 1
CompanyB     | 3

我宁愿看到:

COMPANY_NAME | COUNT(*)
-----------------------
CompanyA     | 25%
CompanyB     | 75%

显然格式化并不是非常重要,因为25,25%,0.25都可以使用。

6 个答案:

答案 0 :(得分:3)

虽然不是单个查询,但以下解决方案将使用变量在SQL中执行:

select @total:=count(*) from search_log;  
select company_id,count( * ) , count( * )/@total as percentage from search_log group by company_id;

答案 1 :(得分:2)

我已经使用视图和自定义函数完成了这样的事情(我不知道函数是否在mysql中可用)。老实说,最好的办法是创建一个小型数据仓库。以这种方式报告这样的事情要快得多。您还可以找到报告数据的新方法。

缺点是,通常情况下,您无法获得“实时”报告。您通常会在晚上汇总所有数据。从好的方面来说,你可以通过这种方式看待趋势。

基本上,在低流量时,您将拍摄数据的快照。然后,你将改变它们并将它们粘贴在一个维度模型中。之后,您的所有报告都非常简单! :)

除此之外,最好的办法是使用标量函数或子查询。

答案 2 :(得分:1)

这个问题以asked before的形式略有不同,我没有看到任何可以避免第二次查询的解决方案 - 如果你想在数据库中完成所有这些。

如果您在自己的应用中执行此操作,则实际上不需要进行第二次查询。只需迭代第一个查询的所有结果,然后将每个组的总计相加。这应该给你“总计”而不必用第二个查询命中数据库。

它可能会强制你迭代结果两次 - 一次得到总数,第二次计算百分比。但仍然可能比进行第二次查询更快。

答案 3 :(得分:1)

如何而不是

SELECT company_name,COUNT(*) FROM companies LEFT OUTER JOIN search_log ON search_log.company_id=companies.id GROUP BY companies.id

SELECT company_name,(COUNT(*)/(select count(*) from search_log) * 100) as percent FROM companies LEFT OUTER JOIN search_log ON search_log.company_id=companies.id GROUP BY companies.id

答案 4 :(得分:0)

我总是做你的下意识反应。

首先,我更喜欢在应用程序端编写数学。 第二,我不知道我对MySQL的数学有多信任。

我认为做count(*)根本就没有效率。

答案 5 :(得分:0)

这将只运行子查询一次,并为您提供您正在寻找的比例。

SELECT company_name, COUNT(*)/t.total FROM companies 
LEFT OUTER JOIN search_log ON search_log.company_id=companies.id
JOIN (SELECT count(*) as total FROM companies) AS t
GROUP BY companies.id