Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/csharp-4.0/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 选择满足某些条件且在某列中具有最大值的行_Sql_Postgresql_Greatest N Per Group - Fatal编程技术网

Sql 选择满足某些条件且在某列中具有最大值的行

Sql 选择满足某些条件且在某列中具有最大值的行,sql,postgresql,greatest-n-per-group,Sql,Postgresql,Greatest N Per Group,我有一个元数据表,用于更新软件包。该表包含列id、名称、版本。我想选择所有行,其中名称是某个给定名称列表中的一个,并且版本是具有该名称的所有行的最大值 例如,鉴于这些记录: +----+------+---------+ | id | name | version | +----+------+---------+ | 1 | foo | 1 | | 2 | foo | 2 | | 3 | bar | 4 | | 4 | bar | 5

我有一个元数据表,用于更新软件包。该表包含列id、名称、版本。我想选择所有行,其中名称是某个给定名称列表中的一个,并且版本是具有该名称的所有行的最大值

例如,鉴于这些记录:

+----+------+---------+
| id | name | version |
+----+------+---------+
| 1  | foo  | 1       |
| 2  | foo  | 2       |
| 3  | bar  | 4       |
| 4  | bar  | 5       |
+----+------+---------+
一个任务给了我最高版本的foo和bar记录,我希望结果是:

+----+------+---------+
| id | name | version |
+----+------+---------+
| 2  | foo  | 2       |
| 4  | bar  | 5       |
+----+------+---------+
到目前为止,我想到的是使用嵌套查询:

选择* 来自更新 哪里 选择id中的id 来自更新 其中name='foo' 按版本说明订购 限制1 或 选择id中的id 来自更新 其中name='bar' 按版本说明订购 限制1 ; 这是可行的,但感觉不对。如果我想过滤更多的名称,我必须多次复制整个子查询。有更好的方法吗?

不存在是避免不需要的次优元组的一种方法:

select distinct on (name) id, name, version
from metadata
where name in ('foo', 'bar')
order by name, version desc

注意:我用zname替换了name,因为它或多或少是postgresql中的一个关键字。

重新阅读Q:

我想选择名称为某个给定列表之一的所有行 的名称,并且版本是具有该名称的所有行的最大值

如果每个名称可以有多个具有最大版本的行,则可以在子查询中使用window函数。需要PostgreSQL 8.4+

SELECT *
FROM  (
   SELECT *, rank() OVER (PARTITION BY name ORDER BY version DESC) AS rnk
   FROM   updates 
   WHERE  name IN ('foo', 'bar')
   )
WHERE rnk = 1;

名称是,但使用它作为标识符仍然是不好的做法,因为它不是描述性的。我认为它在旧版本中被用作表名和列名的类型名。但也许我只是想在所有东西的前面加上一个z…而且,更重要的是,我认为这个查询是不正确的,就像@Clodoaldo的查询一样。它获取每个名称的最大版本,而不是所有行的最大版本。OQ中的示例所需输出确实表明OP需要每个名称的最大版本。不确定,虽然OQ有WHERE子查询或子查询,但她没有提到在ties的情况下该怎么做。是的,SQL很简单:一旦你掌握了语法,一切都变成了数据建模问题。我非常喜欢DISTINCT ON,但它不是查找所有行(可能包括重复名称)的正确工具。更重要的是:这将检索一行,其中通过WHERE子句的每个名称的最大版本,这与问题要求的AIUI略有不同。这似乎是我想要的,并且看起来是迄今为止所有答案中最简单的,所以我接受它。谢谢@亚当:重读后,我发现我似乎误解了你的问题。@erwin:可能是我的问题措辞不正确。对于每个名称,我希望该行具有该名称的所有行的最大版本。对于每个名称,我只需要一行。这个答案不是这样吗?在我的例子中,名称、版本总是唯一的。我应该把这一点放在原来的问题中。我的回答如下:
SELECT *
FROM  (
   SELECT *, rank() OVER (PARTITION BY name ORDER BY version DESC) AS rnk
   FROM   updates 
   WHERE  name IN ('foo', 'bar')
   )
WHERE rnk = 1;