1

PostgreSQL 8.3 でwidgets、次のように呼び出されるテーブルがあるとします。

 id  | type | count
--------------------
  1  | A    |   21
  2  | A    |   29
  3  | C    |    4
  4  | B    |    1
  5  | C    |    4
  6  | C    |    3
  7  | B    |   14

列に基づいて重複を削除し、テーブル内の列の値がtype最も高いものだけを残します。count最終的なデータは次のようになります。

 id  | type | count
--------------------
  2  | A    |   29
  3  | C    |    4  /* `id` for this record might be '5' depending on your query */
  7  | B    |   14

近づいたような気がしますが、重複した列を取り除くために機能するクエリに頭を悩ませているようには見えません。

4

3 に答える 3

2

countは SQL の予約語なので、何らかの方法でエスケープする必要があります。Postgresでそれを行うための構文を頭の中で思い出せないので、角括弧で囲みました(正しくない場合は変更してください)。いずれにせよ、以下は理論的には機能するはずです(ただし、実際にはテストしませんでした):

delete from widgets where id not in (
select max(w2.id) from widgets as w2 inner join 
(select max(w1.[count]) as [count], type from widgets as w1 group by w1.type) as sq
on sq.[count]=w2.[count] and sq.type=w2.type group by w2.[count]
);
于 2009-11-02T05:54:07.217 に答える
1

EXISTS SQL operator を使用して、Asaph よりも少し簡単な答えがあります。

DELETE FROM widgets AS a 
WHERE EXISTS 
  (SELECT * FROM widgets AS b 
   WHERE (a.type = b.type AND b.count > a.count) 
          OR (b.id > a.id AND a.type = b.type AND b.count = a.count))

次の SQL ステートメントが少なくとも 1 つのレコードを返す場合、EXISTS 演算子は TRUE を返します。

于 2009-11-02T16:48:43.920 に答える
0

あなたの要件によると、これはうまくいくはずです:

DELETE 
FROM widgets
WHERE type NOT IN 
(
    SELECT type, MAX(count) 
    FROM widgets 
    GROUP BY type
)
于 2009-11-02T05:57:52.330 に答える