Postgresql

與 SQL 中的按列排序相反

  • January 1, 2021

如果您有一個表格,並且您想按列排序,您可以使用它order by foo來對結果進行排序foo

是否有可能做相反的事情,使得具有相同值的foo行將盡可能遠離彼此?

我正在使用 Postgres 9.5,並希望得到與 Postgres 兼容的答案。

您可以將訂購號 rn 創建為:

select x, row_number() over (partition by x) as rn
from t
order by 2

沒有什麼能保證它們會盡可能地分開,但它至少會將每個 x 分佈在結果集中

假設您要排序的每個值的數量相等(以“最大距離”樣式),您可以執行以下操作:

$$ 1 $$創建一個“映射表”,其中包含所有需要排序的不同值。 $$ 2 $$按照經常需要的順序(升序/降序)從映射表中選擇值,以表示儲存的值。 概念驗證程式碼:

create table t_ (
 id_ serial ,
 num_ integer
);

-- Stick some grouped values into the table.
do $$ 
begin
 for outer_ in 128 .. 256 loop
   for inner_ in 1 .. 10 loop
     insert into t_ (num_) values (outer_);
   end loop;
 end loop;
end$$;  -- 1290 rows

當您執行選擇時,

select * from t_ order by id_;

您將看到 num_ 中的值組合在一起。然後,創建一個“映射”表,使用原始表中的 DISTINCT 值(按(升序)順序)填充它。

create table map_ (
 id_ serial ,
 num_ integer
);

insert into map_ (num_) 
select distinct num_ from t_ order by num_;
-- 129 rows

select * from map_;

然後,加入它們,並使用 MOD() 在輸出中獲取正確的值。最後一個選擇有一列用於原始順序的值,另一列用於新的(“最大距離”)順序。

select t_.id_ t_id_, map_.num_ "new ordering", t_.num_ "old ordering"
from map_ join t_ 
 on ( map_.id_ = mod(t_.id_ , ( select count(*) from map_ )))
order by t_.id_;

我知道如果“原始”值的數量不相等,這並不能解決問題。但是,我認為這可能是朝著正確方向邁出的一步。

引用自:https://dba.stackexchange.com/questions/172355