假设我有表
id | name | number | address
--------------+------------------+---------+-------------------------------------
1 | channel A | 0 | http://stream01
2 | channel B | 2 | http://stream02
3 | channel C | 16 | http://stream03
4 | channel B | 2 | http://stream04
5 | channel B | 16 | http://stream05
6 | channel C | 16 | http://stream06
7 | channel A | 7 | http://stream07
8 | channel A | 5 | http://stream08
9 | channel A | 0 | http://stream09
...etc
我想删除重复的频道(具有相同名称和号码的行)。但我希望结果包含其他列以及名称和编号。
问题是我删除重复项后选择的id
和address
。我很高兴选择它找到的第一个。因此,例如,上表的结果应为
id | name | number | address
--------------+------------------+---------+-------------------------------------
1 | channel A | 0 | http://stream01
2 | channel B | 2 | http://stream02
3 | channel C | 16 | http://stream03
5 | channel B | 16 | http://stream05
7 | channel A | 7 | http://stream07
8 | channel A | 5 | http://stream08
...etc
我意识到我的查询中可能需要SELECT name,number FROM table GROUP BY name,number
,查询应该从SELECT id,name,number,address FROM (..)
开始,但我想不出在一个查询中执行此操作的方法。
有什么想法吗?
答案 0 :(得分:4)
SELECT DISTINCT ON (name,number)
id,
name,
number,
address
FROM table
ORDER BY name,number,id;
答案 1 :(得分:0)
SELECT min(id),
name,
number,
min(address)
FROM the_table
GROUP BY name, number;
修改强>
如果您需要匹配ID和地址,那么以下是另一种解决方案:
SELECT id,
name,
number,
address
FROM (
SELECT id,
name,
number,
address,
row_number() over (partition by name, number order by id) as rn
FROM the_table
) t
WHERE rn = 1
答案 2 :(得分:0)
这应该足够了:
SELECT MIN(id), name, number, address FROM table GROUP BY name, number
答案 3 :(得分:0)
我认为最容易理解的方法是使用视图或公用表表达式。我将使用公用表表达式。
create table test (
id integer primary key,
name varchar(20) not null,
number integer not null,
address varchar(30) not null
);
insert into test values
(1, 'channel A', 0, 'http://stream01'),
(2, 'channel B', 2, 'http://stream02'),
(3, 'channel C', 16, 'http://stream03'),
(4, 'channel B', 2, 'http://stream04'),
(5, 'channel B', 16, 'http://stream05'),
(6, 'channel C', 16, 'http://stream06'),
(7, 'channel A', 7, 'http://stream07'),
(8, 'channel A', 5, 'http://stream08'),
(9, 'channel A', 0, 'http://stream09');
with unique_name_num as (
select distinct name, number
from test
),
min_id as (
select number, name, min(id) id
from test
group by number, name
)
select t.*
from test t
inner join unique_name_num u on u.name = t.name and u.number = t.number
inner join min_id m on m.number = t.number and m.name = t.name and m.id = t.id
order by t.name, t.number