在反向 int 对中使用 DISTINCT 重复消除

Usage of DISTINCT in reversed int pairs duplicates elimination

我有以下问题:

create table memorization_word_translation
(
    id           serial  not null
    from_word_id integer not null
    to_word_id   integer not null
);

这个 table 存储整数对,它们通常以相反的顺序排列,例如:

35 36
35 37
36 35
37 35
37 39
39 37

问题是 - 如果我进行查询,例如:

select * from memorization_word_translation
where from_word_id = 35 or to_word_id = 35

我会得到

35 36
35 37
36 35  - duplicate of 35 36
37 35  - duplicate of 35 37

这个例子中如何使用DISTINCT来过滤掉所有的重复项,即使它们被颠倒了? 我只想像这样保留它:

35 36
35 37

您可以使用 ROW_NUMBER() window 函数:

select from_word_id, to_word_id
from (
  select *,
         row_number() over (
           partition by least(from_word_id, to_word_id), 
                        greatest(from_word_id, to_word_id)
           order by (from_word_id > to_word_id)::int
         ) rn                                                         
  from memorization_word_translation 
  where 35 in (from_word_id, to_word_id)
) t
where rn = 1 

参见demo

demo:db<>fiddle

您可以结合 DISTINCT ON.

尝试使用小型排序算法(此处为比较)

DISTINCT ON 子句适用于任意列或术语,例如在元组上。此 CASE 子句将两列排序为元组并删除绑定的(有序的)元组。可以在 SELECT 语句中返回源列:

select distinct on (
    CASE 
        WHEN (from_word_id >= to_word_id) THEN (from_word_id, to_word_id)
        ELSE (to_word_id, from_word_id)
    END 
)
    * 
from memorization_word_translation
where from_word_id = 35 or to_word_id = 35