【问题标题】:Possible to compare COUNT(*) from multiple rows on MySQL?可以比较 MySQL 上多行的 COUNT(*) 吗?
【发布时间】:2010-10-26 12:39:52
【问题描述】:

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

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 都是可用的。

【问题讨论】:

  • 占什么百分比?
  • 占总数的百分比,所以如果我得到以下结果:CompanyA,1 AND CompanyB,3 -- 我宁愿看到 25% 和 75% 而不是 1 和 3
  • @Adriano Varoli Piazza -- 已修复。

标签: mysql


【解决方案1】:

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

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

【讨论】:

  • 赞成一个有效的想法,但因为我使用的是 PHP,所以我认为不可能实现这个想法。
  • 我认为它也可以在 PHP 上运行。这只是普通的sql。只需在同一个连接/语句上运行两个查询。
【解决方案2】:

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

缺点是您通常无法获得“实时”报告。您通常会在晚上汇总所有数据。好处是,您可以通过这种方式查看一段时间内的趋势。

基本上,在交通流量较低的时段,您会拍摄数据快照。然后,您将对它们进行变异并将它们粘贴到维度模型中。之后,您的所有报告都非常容易! :)

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

【讨论】:

    【解决方案3】:

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

    如果您在应用中执行此操作,您实际上不需要执行第二次查询。只需遍历第一个查询的所有结果并将每个组的总数相加即可。这应该可以为您提供“总计”,而无需通过第二次查询来访问数据库。

    它可能会迫使您将结果迭代两次 - 一次获取总数,第二次计算百分比。但仍然可能比进行第二次查询更快。

    【讨论】:

      【解决方案4】:

      用这个代替

      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
      

      【讨论】:

      • 是的,但就像我说的那样,如果可能的话我不想使用子查询
      • 错过了你的那部分问题
      • 没问题,仍然是一个不错的答案,我可能最终不得不做的事情
      • 子查询会不会被mysql缓存?
      【解决方案5】:

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

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

      我认为count(*) 一点也不低效。

      【讨论】:

      • 并不是我认为 COUNT(*) 效率低下,而是如果我使用子查询,我将在查询的顶部每行执行一次
      【解决方案6】:

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

      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
      

      【讨论】:

        猜你喜欢
        • 2010-09-22
        • 1970-01-01
        • 1970-01-01
        • 2012-10-19
        • 2010-10-16
        • 1970-01-01
        • 1970-01-01
        • 2012-06-18
        • 2011-04-22
        相关资源
        最近更新 更多