简体   繁体   English

SQL如何获取分组表中表中列的最大值的行

[英]SQL how to get rows with max value of a column in the table in grouped rows

I have a table with columns ('name', 'maj', 'min', 'patch') for each name there can be several major/minor/patch versions. 我有一个带有列('name','maj','min','patch')的表,每个名称可以有几个主要/次要/补丁版本。 For each name I need to get the major + minor values for the max 'patch' for that major/minor. 对于每个名称,我需要获取该主要/次要的最大“补丁”的主要和次要值。

eg table 'data' 例如表“数据”

|id|name|maj|min|patch|
|1 |n1  |1  |0  | 1   |
|2 |n1  |1  |0  | 2   |
|3 |n1  |1  |0  | 3   |
|4 |n2  |1  |0  | 1   |
|5 |n2  |2  |0  | 1   |
|6 |n2  |2  |0  | 2   |

Expected output: 预期产量:

|id|name|maj|min|patch|
|3 |n1  |1  |0  | 3   |
|4 |n2  |1  |0  | 1   |
|6 |n2  |2  |0  | 2   |

I have only managed to get this data grouped by these fields and ordered but I don't know to get only the rows with max patch for each major/minor 我只能设法按这些字段对数据进行分组并排序,但我不知道仅针对每个主要/次要获得具有最大补丁的行

SELECT id, name, maj, min, patch FROM data group by name, maj, min order by name, patch desc

The following query gets close to what you want: 以下查询接近您想要的内容:

SELECT
    name,
    maj,
    `min`,
    MAX(patch) AS patch
FROM data
GROUP BY
    name,
    maj,
    `min`;

But, this doesn't include the id column, which is not part of the aggregation query. 但是,这不包括id列,它不是聚合查询的一部分。 If you want a general approach to include the entire matching rows, then consider using ROW_NUMBER : 如果您想采用一种通用方法来包括整个匹配的行,请考虑使用ROW_NUMBER

WITH cte AS (
    SELECT *, ROW_NUMBER() OVER (PARTITION BY name, maj, `min` ORDER BY patch DESC) rn
    FROM data
)

SELECT id, name, maj, `min`, patch
FROM cte
WHERE rn = 1;

With NOT EXISTS: 有不存在:

select t.* from tablename t
where not exists (
  select 1 from tablename
  where name = t.name and maj = t.maj and min = t.min and patch > t.patch
)  

See the demo . 参见演示
Results: 结果:

| id  | name | maj | min | patch |
| --- | ---- | --- | --- | ----- |
| 3   | n1   | 1   | 0   | 3     |
| 4   | n2   | 1   | 0   | 1     |
| 6   | n2   | 2   | 0   | 2     |

You can also do this with a correlated subquery: 您也可以使用相关子查询来执行此操作:

selet t.*
from t
where t.patch = (select max(t2.patch)
                 from t t2
                 where t2.name = t.name and
                       t2.maj = t.maj and
                       t2.min = t.min
                );

If you have a large database, then an index on (name, maj, min, patch) will provide good performance. 如果您的数据库很大,则索引(name, maj, min, patch)将提供良好的性能。

You can simply using having Clause to achieve it Simple sample 您可以简单地使用拥有子句来实现它。

SELECT id, name, maj, min, max(patch) AS max_patch FROM data GROUP BY patch DESC HAVING MAX(patch) >1;

Hope that's help you 希望对您有帮助

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM