具有连接和计数的 mysql 查询

标签 mysql database

我需要帮助从连接在一起的 mysql 数据库中两个不同表的列中获取前 5 个结果及其计数。

table1 cols
-------
id, country, timestamp

table2 cols
--------
id, table1_id, reason

想要获取的结果是前 5 个国家/地区及其在两个时间戳之间找到的次数,以及前 5 个原因及其用于生成第一个计数的所有行的计数。 table1 和 table2 之间存在一对多关系。这让我很困惑,我很感激你能给我的任何见解。

最佳答案

尚不完全清楚您想要返回什么结果集。

这可能对您有一些帮助:

SELECT t.country
     , COUNT(DISTINCT t.id) AS count_table1_rows
     , COUNT(r.id)          AS count_table2_rows
     , COUNT(*)             AS count_total_rows
  FROM table1 t
  LEFT
  JOIN table2 r
    ON r.table1_id = t.id
 WHERE t.timestamp >= NOW() - INTERVAL 7 DAY
   AND t.timestamp  < NOW()
 GROUP BY t.country
 ORDER BY COUNT(DISTINCT t.id) DESC
 LIMIT 5

这将返回最多 5 行,每个国家/地区一行,其中包含 table1 中的行数、table2 中找到的行数以及返回的总行数。

LEFT 关键字指定“外部”连接操作,这样即使在 table2 中没有找到匹配的行,也会返回 table1 中的行。

要获取与每个国家/地区关联的每个“原因”的计数,您可以执行以下操作:

SELECT t.country
     , COUNT(DISTINCT t.id) AS count_table1_rows
  FROM table1 t
  LEFT
  JOIN ( SELECT s.country
              , r.reason
              , COUNT(*) AS cnt_r
           FROM table1 s 
           JOIN table2 r
             ON s.table1_id = t.id
          WHERE s.timestamp >= NOW() - INTERVAL 7 DAY
            AND s.timestamp  < NOW()
          GROUP
             BY s.country
              , r.reason
       ) u
    ON u.country = t.country 
 WHERE t.timestamp >= NOW() - INTERVAL 7 DAY
   AND t.timestamp  < NOW()
 GROUP
    BY t.country
     , u.reason
 ORDER
    BY COUNT(DISTINCT t.id) DESC
     , t.country DESC
     , u.cnt_r DESC
     , u.reason DESC

此查询不会“限制”返回的行。可以将查询修改为仅返回行的子集,但这可能会变得复杂。在我们消除添加“前 5 名中的前 5 名”类型限制的复杂性之前,我们希望确保查询返回的行是我们实际想要的行的超集。

关于具有连接和计数的 mysql 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25675316/

相关文章:

ruby-on-rails - Rails 事件记录查询一起列出的 2 个属性

mysql - 仅订购嵌套模型数据 Sequelize

database - 糟糕的数据库设计——我的表太大了吗?

mysql - 有关 Mysql 计数的任何建议

MySQL 存储过程 - 如何在 FROM 子句中使用参数

mysql - 需要在表中创建多少列来保存附件的 url 路径?

mysql - 哈希密码必须经过清理吗?

mysql - 如何处理 Laravel 中的 mySql POINT 字段

mysql - 内连接查询(sql)

mysql - 使用选项值设置搜索条件的变量