Postgresql 删除重复的反向对
Postgresql remove duplicate reversed pairs
我有这个table:
origin destination
new york seattle
new york chicago
new york portland
seattle new york
seattle chicago
chicago new york
我必须构建一个图表,所以我需要删除所有重复的反向对:
origin destination oneway
new york seattle 0
new york chicago 0
new york portland 1
seattle chicago 1
我已经读过这个post:
SQL -- Remove duplicate pairs
但它对我没有用,因为我有字符串归档。
谢谢
一种方法使用聚合:
select origin, destination,
(case when exists (select 1
from t t2
where t2.origin = t.destination and t2.destination = t.origin
)
then 0 else 1
end) as one_way
from t
where origin < destination
union all
select origin, destination, 1
from t
where origin > destination;
另一种方法使用 window 函数:
select origin, destination, (cnt = 1)::int as one_way
from (select t.*,
count(*) over (partition by least(origin, destination), greatest(origin, destination)) as cnt
from t
) t
where origin < destination or
(origin > destination and cnt = 1);
row_number
和 count
使用 least
和 greatest
的一个选项。
select origin,dest,case when cnt_per_pair=1 then 1 else 0 end as one_way
from (select t.*,row_number() over(partition by least(origin,dest),greatest(origin,dest)
order by dest) as rnum,
count(*) over(partition by least(origin,dest),greatest(origin,dest)) as cnt_per_pair
from tbl t
) t
where rnum=1
我有这个table:
origin destination
new york seattle
new york chicago
new york portland
seattle new york
seattle chicago
chicago new york
我必须构建一个图表,所以我需要删除所有重复的反向对:
origin destination oneway
new york seattle 0
new york chicago 0
new york portland 1
seattle chicago 1
我已经读过这个post: SQL -- Remove duplicate pairs 但它对我没有用,因为我有字符串归档。
谢谢
一种方法使用聚合:
select origin, destination,
(case when exists (select 1
from t t2
where t2.origin = t.destination and t2.destination = t.origin
)
then 0 else 1
end) as one_way
from t
where origin < destination
union all
select origin, destination, 1
from t
where origin > destination;
另一种方法使用 window 函数:
select origin, destination, (cnt = 1)::int as one_way
from (select t.*,
count(*) over (partition by least(origin, destination), greatest(origin, destination)) as cnt
from t
) t
where origin < destination or
(origin > destination and cnt = 1);
row_number
和 count
使用 least
和 greatest
的一个选项。
select origin,dest,case when cnt_per_pair=1 then 1 else 0 end as one_way
from (select t.*,row_number() over(partition by least(origin,dest),greatest(origin,dest)
order by dest) as rnum,
count(*) over(partition by least(origin,dest),greatest(origin,dest)) as cnt_per_pair
from tbl t
) t
where rnum=1