【问题标题】:Finding Most Frequent Values in a Table Associated with a Parent Id Column in Another在与另一个表中的父 ID 列关联的表中查找最常见的值
【发布时间】:2015-06-02 23:09:36
【问题描述】:

我有两个要连接的表。他们有一对多的关系。我想做一个查询,为每个父 ID 提取最频繁的“许多”表

我有一个这样的查询,它处于我正在尝试做的事情的开始阶段:

SELECT  p.profile, up.value, COUNT(*) AS theCount FROM `profiles` AS p
JOIN user_profile AS up ON p.id = up.profile_id
GROUP BY `profile`, `value`
ORDER BY p.profile ASC, theCount DESC;

现在这个查询的问题是它会显示许多表中的所有值,并且只是将它们从最多到最少分组。例如:

如果表 profile 的值为 val 1val 2 并且表 user_profiles 的值为 AppleAppleOrange,其 parent_id 为 val 1Pear val 2 在第一个表中,上面的查询会将它们分组如下:

val 1Apple2

val 1Orange1

val 2Pear1

现在我想要的是:

val 1Apple2

val 2Pear1

我只想为父级显示最高值。或者,如果情况只有一个值(例如 val 2),则显示该值。

现在,我可以在子查询中轻松完成此操作(为每个父值设置一个限制 1;按theCount DESC 排序)。 但是,是否有 (1) 一种方法可以做到这一点没有子查询?或(2)MySQL函数或其他方式来做到这一点?我正在努力使这些查询保持非常快速和高性能。

如果你能告诉我子查询不会影响性能,我也会选择它作为答案。

【问题讨论】:

  • 使用"greatest N per group" pattern here 并加入一个产生计数的子查询,这应该是可以实现的和高性能的。连接的子查询不会遇到与子查询相同的严重性能问题。
  • 如果您可以在sqlfiddle.com 使用您的两张表设置此示例集,那将有所帮助。
  • @MichaelBerkowski 根据您提供的链接,我相信您对我需要的东西有确切的想法。如果您认为子查询可以,那么我应该尝试一下并比较查询的时间。
  • 虽然它在概念上有点老套,但 Gordon 的使用 group_concat() 和字符串 manips 的方法可能比用户变量方法更快并且更容易实现。试试看。
  • @MichaelBerkowski 我试过了,其实很快。

标签: mysql sql


【解决方案1】:

对于这类问题,我认为group_concat()/substring_index()技巧是MySQL中最简单的方法:

SELECT profile, substring_index(group_concat(up.value order by theCount desc), ',', 1) as MostCommonValue,
       theCount
FROM (SELECT  p.profile, up.value, COUNT(*) AS theCount
      FROM `profiles` p JOIN
            user_profile up 
            ON p.id = up.profile_id
      GROUP BY `profile`, `value`
     ) pv
GROUP BY profile
ORDER BY p.profile ASC, theCount DESC;

这种方法有缺点。例如,如果value 可以包含逗号,则需要使用不同的分隔符。更重要的是,group_concat() 中间值有一个最大长度(但您将参数设置为更大的值)。但是,它在许多情况下都非常有效。

【讨论】:

  • 嗯,这确实很快。而且您没有子查询就做到了...所以我认为这就是答案。
猜你喜欢
  • 2017-04-21
  • 1970-01-01
  • 2021-03-07
  • 1970-01-01
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多