Postgresql
與 SQL 中的按列排序相反
如果您有一個表格,並且您想按列排序,您可以使用它
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_;
我知道如果“原始”值的數量不相等,這並不能解決問題。但是,我認為這可能是朝著正確方向邁出的一步。