ORDER BY和ROW_NUMBER()优先级- DB2和PostgreSQL返回不同的结果,但查询相同

cgfeq70w  于 2022-11-07  发布在  DB2
关注(0)|答案(3)|浏览(185)

我试图理解为什么DB2做了我所期望的事情,而Postgres却没有。
我已经成功地复制了我在这个相当简单的自包含查询中看到的行为。

with mytables(id,animal) as (
                 values (1,'Cat'),(2,'Dog'),(3,'Mouse') 
)
select *,
       case 
         when animal = 'Dog' then 0
         when animal = 'Cat' then 1
         else 2
       end my_order_by,
       row_number() over() as rank 
from mytables  
order by my_order_by ;

DB2将返回我期望看到的结果:

ID  Animal  MY_ORDER_BY RANK
2   Dog     0           1
1   Cat     1           2
3   Mouse   2           3

波斯特格雷斯返回:

ID  Animal  MY_ORDER_BY RANK
2   Dog     0           2
1   Cat     1           1
3   Mouse   2           3

在我看来,Postgres是基于ID而不是order by应该强制执行的row_number。有没有办法解决这个问题,使Postgres能够执行这里所期望的操作?
使用谷歌CloudSQL和DB2 v11上的PostgreSQL 13,顺便说一下。

soat7uwm

soat7uwm1#

将顺序添加到row_number,以获得所需的排序。
第一个

  • db〈〉小提琴
xxe27gdn

xxe27gdn2#

正如所指出的,ROW_NUMBER()排序由它自己的ORDER BY子句ROW_NUMBER() OVER(ORDER BY ... [PARTITION BY ...])控制
一个比nbk的答案更简洁的处理方法是

with mytables(id,animal) as (
                 values (1,'Cat'),(2,'Dog'),(3,'Mouse') 
)
, add_my_order as (
select mytables.*,
       case 
         when animal = 'Dog' then 0
         when animal = 'Cat' then 1
         else 2
       end my_order_by
from mytables  
)
select add_my_order.*,
       row_number() over(my_order_by) as rank,
from add_my_order          
order by my_order_by;
omjgkv6w

omjgkv6w3#

这是编写与Charles和nbk相同的查询的另一种方法,其中case作为横向子查询

with mytables(id,animal) as (
                 values (1,'Cat'),(2,'Dog'),(3,'Mouse') 
)
select mytables.*,
       my_order_by,
       row_number() over (order by my_order_by) as rank
from mytables
  cross join lateral (values (case 
         when animal = 'Dog' then 0
         when animal = 'Cat' then 1
         else 2
       end)) ob (my_order_by)
order by my_order_by;

db<>fiddle

相关问题