2012-03-08 17 views
0

は私が重複したチャンネル(同じ名前と番号の行)を削除したいテーブルPostgreSQLのGROUP BYの問題

 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 

があるとします。しかし、結果に名前と番号とともに他の列が含まれているようにしたい。

問題はidaddress重複を削除した後に選択する問題です。私は最初に見つけたものを選んで喜んでいます。したがって、たとえば、上記の表から結果が

 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 (..)を始める必要がありますが、私はただの方法を考えることはできません1つのクエリでこれを行います。

アイデア?

+0

「削除」とは、行を削除するか、結果に表示しないことを意味しますか? –

+0

結果に含まれていません。私はほとんどそれを持っている気がします - 'SELECT id、name、number、addressからのテーブルの選択(名前の選択、GROUP BYの名前からの数字の番号、数字の)AS j USING(名前、番号)'。あまり働かなかった。 – tbh1

答えて

4
SELECT DISTINCT ON (name,number) 
     id, 
     name, 
     number, 
     address 
    FROM table 
ORDER BY name,number,id; 
+0

ありがとうございます。今日はDISTINCT ONを試しましたが、うまくいきませんでした。私の実際のクエリは最後に 'ORDER BY'を持ち、' ​​SELECT DISTINCT ON式は最初のORDER BY式と一致する必要があります 'というエラーを投げていたからです。私は '()'でクエリ全体をラップし、最後に 'SELECT * FROM'を準備し、' ORDER BY'を貼り付けることでこれを修正できます。 – tbh1

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 
+0

min(id)とmin(address)が同じ行にない場合、元のテーブルにない行を製造する効果がありますか? –

+0

はい、あなたは正しいです。 tbh1が返される値を気にしないというような質問を理解しました。 –

+0

ありがとうございます。私の実際の質問は、疑問にぶつかったものよりもかなり複雑です。 'min()'のすべてをラップしても、私の場合は最高の解決策ではありませんが、感謝します。 – tbh1

0

十分にする必要があること:

SELECT MIN(id), name, number, address FROM table GROUP BY name, number 
+0

エラーが発生します。アドレスに集計関数を適用するか、GROUP BY句に含めるかのいずれかを行う必要があります –

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 
+0

ありがとう、ありがとう。 – tbh1