28

在 postgres 中,您可以使用 查询组中的第一个值DISTINCT ON如何在 Oracle 中实现这一点?

从 postgres 手册:

SELECT DISTINCT ON ( expression [, ...] ) 只保留给定表达式计算结果为相等的每组行的第一行。DISTINCT ON 表达式使用与 ORDER BY 相同的规则进行解释(见上文)。请注意,除非使用 ORDER BY 确保所需的行首先出现,否则每组的“第一行”是不可预测的。

例如,对于给定的表:

 col1 | col2 
------+------
 A    | AB
 A    | AD
 A    | BC
 B    | AN
 B    | BA
 C    | AC
 C    | CC

升序排序:

> select distinct on(col1) col1, col2 from tmp order by col1, col2 asc;
 col1 | col2 
------+------
 A    | AB
 B    | AN
 C    | AC

降序排序:

> select distinct on(col1) col1, col2 from tmp order by col1, col2 desc;
 col1 | col2 
------+------
 A    | BC
 B    | BA
 C    | CC
4

2 回答 2

42

通过使用函数或使用or函数first_value()之一,可以在 Oracle 中复制相同的效果。rank()row_number()

这两种变体也适用于 Postgres。

first_value()

select distinct col1, 
first_value(col2) over (partition by col1 order by col2 asc)
from tmp

first_value给出分区的第一个值,但对每一行重复它,因此有必要结合使用它distinct来为每个分区获取单行.

row_number()/rank()

select col1, col2 from (
  select col1, col2, 
  row_number() over (partition by col1 order by col2 asc) as rownumber 
  from tmp
) foo
where rownumber = 1

在此示例中替换row_number()为产生相同的结果。rank()

这个变体的一个特点是它可以用于获取给定分区的前 N​​行(例如“最后 3 个更新”),只需更改rownumber = 1rownumber <= N.

于 2012-05-09T11:45:15.377 回答
2

如果您有两个以上的字段,则使用 beerbajays answer 作为子查询(注意按 DESC 顺序):

select col1,col2, col3,col4 from tmp where col2 in
(
select distinct 
first_value(col2) over (partition by col1 order by col2 DESC) as col2
from  tmp
--WHERE you decide conditions
)
于 2015-05-15T06:57:33.313 回答