显示每个唯一ID的所有重复最大值

时间:2019-03-02 10:47:53

标签: mysql sql

我有一些看起来像这样的数据表:

表1:

 name | t2id  | percentage
-------------------------
  A   |  1    |    75
  B   |  1    |    75
  C   |  1    |    50
  D   |  2    |    30
  E   |  2    |    45
  F   |  2    |    45
  G   |  3    |    80
  H   |  3    |    70
  E   |  3    |    60

表2:

id  | name
-----------
 1  | NAME1
 2  | NAME2
 3  | NAME3

我得到每个t2id的最大百分比,并显示以下内容:

SELECT t1.name, t2.name, MAX(t1.percentage) AS MAX_p 
FROM table1 t1 INNER JOIN table2 t2 ON t1.t2id = t2.id GROUP BY t1.t2id;

输出:

t1.name | t2.name | MAX_p
--------------------------
   A    |  NAME1  |  75
   E    |  NAME2  |  45
   G    |  NAME3  |  80

现在我也在尝试显示每个t2id的重复最大值,如下所示:

t1.name | t2.name | MAX_p
--------------------------
   A    |  NAME1  |  75
   B    |  NAME1  |  75
   E    |  NAME2  |  45
   F    |  NAME2  |  45
   G    |  NAME3  |  80

我似乎找不到解决方案,我一直在尝试子查询,但无法获取它以显示正确的输出。如果有人可以帮助我解决该问题,将不胜感激

3 个答案:

答案 0 :(得分:1)

如果您使用的是MySQL 8或更高版本,则可以在此处使用RANK

WITH cte AS (
    SELECT t1.name, t2.name AS t2name, t1.percentage,
        RANK() OVER (PARTITION BY t2.id ORDER BY t1.percentage DESC) rnk
    FROM table1 t1
    INNER JOIN table2 t2
        ON t1.t2id = t2.id
)

SELECT name, t2name, percentage
FROM cte
WHERE rnk = 1;

如果您需要一个可以在MySQL版本8之前运行的版本,那么我们必须做更多的工作:

SELECT t1.name, t2.name, t1.percentage
FROM table1 t1
INNER JOIN table2 t2
    ON t1.t2id = t2.id
INNER JOIN
(
    SELECT t2.id, MAX(t1.percentage) AS max_percentage
    FROM table1 t1
    INNER JOIN table2 t2
        ON t1.t2id = t2.id
    GROUP BY t2.id
) t3
    ON t2.id = t3.id AND t1.percentage = t3.max_percentage;

答案 1 :(得分:1)

这是标准的SQL,可与所有版本的MySQL(和其他RDBMS)一起使用

SELECT t1.name AS t1name, t2.name AS t2name, t1.percentage
FROM table1 t1 
INNER JOIN table2 t2 ON t1.t2id = t2.id 
INNER JOIN 
    (SELECT t2id, MAX(percentage) AS MAX_p 
     FROM table1 t1
     GROUP BY t2id) m
  ON t1.t2id = m.t2id AND t1.percentage=m.MAX_p

答案 2 :(得分:0)

我将使用相关的子查询来做到这一点:

did not change the type

此方法的优点是性能-它不会对所有数据进行汇总。实际上,有了SELECT t1.name, t2.name, t1.percentage AS MAX_p FROM table1 t1 INNER JOIN table2 t2 ON t1.t2id = t2.id WHERE t1.percentage = (SELECT MAX(tt1.percentage) FROM table1 tt1 WHERE tt1.t2id = t1.t2id ); 上的索引,table1(t2id, percentage)子句应该是快速的表查找。

这样写起来可能更快:

WHERE

这需要在SELECT t1.name, (SELECT t2.name FROM table2 t2 WHERE t1.t2id = t2.id) as t2_name, t1.percentage AS MAX_p FROM table1 t1 WHERE t1.percentage = (SELECT MAX(tt1.percentage) FROM table1 tt1 WHERE tt1.t2id = t1.t2id ); 上建立索引。

从本质上讲,这应该是对table2(id, name的扫描,并在每行上进行快速索引查找以进行过滤。然后在table1上进行附加索引查找以获取名称。