我运行了一个查询,该查询返回了一个这样的表。
d | e | f
---+-----+----
2 | 103 | C
6 | 201 | AB
1 | 102 | B
1 | 102 | B
1 | 102 | B
1 | 102 | B
1 | 102 | B
3 | 105 | E
3 | 105 | E
3 | 105 | E
我想要的是获取不同的行,但是要有序。基本上我想要这个:
2 | 103 | C
6 | 201 | AB
1 | 102 | B
3 | 105 | E
我尝试过distinct
和group by
,但是他们并不总是保留职位(他们在我遇到的其他情况下保留了职位)。关于如何轻松完成此操作的任何想法,还是需要使用其他功能,例如rank
?
答案 0 :(得分:1)
在以下情况下的用例:
order by case when f=C then 1 when f=AB then 2
when f=B then 3 when f=E then 5 else null end
答案 1 :(得分:1)
SQL表表示无序集。除非您具有带有列或表达式的显式order by
,否则不进行排序。
如果您有这样的订购,则可以使用group by
做您想做的事情:
select d, e, f
from t
group by d, e, f
order by min(a); -- assuming a is the column that specifies the ordering
答案 2 :(得分:0)
您可以尝试在order by
ctid列中描述行的物理位置,以识别行。
表中行版本的物理位置。请注意,尽管可以使用ctid快速定位行版本,但是如果通过VACUUM FULL更新或移动了行的ctid,则该行的ctid将会更改。因此,ctid不能用作长期行标识符。应该使用OID或更好的用户定义序列号来标识逻辑行。
使用row_number
和 windows函数通过ctid
生成行号。
然后得到rn = 1
和order by ctid
CREATE TABLE T(
d int,
e int,
f varchar(5)
);
insert into t values (2,103, 'C');
insert into t values (6,201, 'AB');
insert into t values (1,102, 'B');
insert into t values (1,102, 'B');
insert into t values (1,102, 'B');
insert into t values (1,102, 'B');
insert into t values (1,102, 'B');
insert into t values (3,105, 'E');
insert into t values (3,105, 'E');
insert into t values (3,105, 'E');
查询1 :
select d,e,f
from (
select d,e,f,ctid,row_number() over(partition by d,e,f order by ctid) rn
FROM T
)t1
where rn = 1
order by ctid
Results :
| d | e | f |
|---|-----|----|
| 2 | 103 | C |
| 6 | 201 | AB |
| 1 | 102 | B |
| 3 | 105 | E |