mysql 为其他两列的每个唯一组合选择具有最大值(列值)的行

vuv7lop3  于 2023-06-28  发布在  Mysql
关注(0)|答案(1)|浏览(165)

我正在使用如下的示例表。一个数据集有多个组,每次对表进行写入时,数据集的RunNumber沿着每个组的数据和总数都会增加。每个数据集/组组合通常有多行,示例如下:
| 集团|数据集|共计| Total |
| - -----|- -----|- -----| ------------ |
| 第一组|数据集A|十个| 10 |
| 第一组|数据集A|二十个| 20 |
| 第一组|数据集A|三十| 30 |
| 组2|数据集A|十五| 15 |
| 第一组|数据集B| 5个| 5 |
| 组2|数据集B|十个| 10 |
| 第三组|数据集A|三十| 30 |
| 第三组|数据集A|三十| 30 |
| 第一组|数据集C|十五| 15 |
| 组2|数据集C|五十| 50 |
| 组2|数据集C|七十| 70 |
| 组2|数据集C|九十| 90 |
我想做的是对于每个Dataset和Group的组合都是必不可少的,返回给定Dataset/Group组合中具有max(RunNumber)的行的所有数据。例如,上面的示例将返回以下内容:
| 集团|数据集|共计| Total |
| - -----|- -----|- -----| ------------ |
| 第一组|数据集A|三十| 30 |
| 组2|数据集A|十五| 15 |
| 第一组|数据集B| 5个| 5 |
| 组2|数据集B|十个| 10 |
| 第三组|数据集A|三十| 30 |
| 第一组|数据集C|十五| 15 |
| 组2|数据集C|七十| 70 |
| 组2|数据集C|九十| 90 |
在Dataset/Groups匹配的情况下,所有行都保留该给定组合的最大RunNumber。现在,我将其分为两个单独的查询,首先查询所有不同的Dataset/Group组合的max(RunNumber),然后对所有匹配项执行select *。任何帮助将不胜感激,提前感谢!

rxztt3cl

rxztt3cl1#

在MySQL 5.x中,你可以使用子查询。

SELECT * 
FROM your_table
WHERE (`Group`, Dataset, RunNumber) IN (
    SELECT `Group`, Dataset, MAX(RunNumber) AS MaxRunNumber
    FROM your_table
    GROUP BY `Group`, Dataset
  );

测试 *db<>fiddle here *

备选方案

--
-- LEFT JOIN on bigger
--
SELECT t.* 
FROM your_table t
LEFT JOIN your_table t2
  ON t2.`Group` = t.`Group`
 AND t2.Dataset = t.Dataset
 AND t2.RunNumber > t.RunNumber
WHERE t2.RunNumber IS NULL
ORDER BY t.`Group`, t.Dataset;

--
-- where NOT EXISTS on bigger
--
SELECT * 
FROM your_table t
WHERE NOT EXISTS (
  SELECT 1
  FROM your_table t2
  WHERE t2.`Group` = t.`Group`
    AND t2.Dataset = t.Dataset
    AND t2.RunNumber > t.RunNumber
)
ORDER BY `Group`, Dataset;

--
-- Emulating DENSE_RANK = 1 with variables
-- Works also in 5.x
--
SELECT RunNumber, `Group`, Dataset, Total
FROM
(
  SELECT 
    @rnk:=IF(@ds=Dataset AND @grp=`Group`, IF(@run=RunNumber, @rnk, @rnk+1), 1) AS Rnk
  , @grp := `Group` as `Group`
  , @ds := Dataset as Dataset
  , @run := RunNumber as RunNumber
  , Total
  FROM your_table t
  CROSS JOIN (SELECT @grp:=null, @ds:=null, @run:=null, @rnk := 0) var
  ORDER BY `Group`, Dataset, RunNumber DESC
) q
WHERE Rnk = 1
ORDER BY `Group`, Dataset;

--
-- DENSE_RANK = 1
-- MySql 8 and beyond. 
--
SELECT *
FROM
(
  SELECT *
  , DENSE_RANK() OVER (PARTITION BY `Group`, Dataset ORDER BY RunNumber DESC) AS rnk
  FROM your_table
) q
WHERE rnk = 1
ORDER BY `Group`, Dataset;

相关问题