2017-08-30 11 views
1

重複した行を取得できたデータベースがあります。SQLクエリ:同じ値でPostgreSQLから行を削除する

データベースには、次の値が含まれています

-------------------------------------------------------------- 
| id | did | sensorid | timestamp | data | db_timestamp | 
-------------------------------------------------------------- 
| int | string | int  | bigint | jsonb | bigint  | 
-------------------------------------------------------------- 

timestampdb_timestampは私が多くを得るために管理しているUNIXタイムスタンプ(1970年1月1日からのミリ秒午前12:00:00)

です重複した値があり、それらを「破棄」するための高速なメソッドが必要です。それらが重複していることを示す値は、did,sensoridおよびtimestampです。つまり、これらが同じ行が見つかった場合は重複しています。

私は重複を見つけるために次のクエリを作成しましたが、今はそれらを削除する方法を見つける必要があります。

SELECT did, sensorid, timestamp, COUNT(*) 
FROM <db_name> 
GROUP BY did, sensorid, timestamp 
HAVING COUNT(*) > 1 
ORDER BY sensorid, timestamp; 

私のDBはほとんど1.200.000.000行が含まれており、私はこれらの重複のあまりにも多くを持っているので、私は私のためにそれらを削除しますPythonスクリプトを作成している知っています。私はしかし、私のpythonスクリプトを使用して私がそれを必要とするほど速くはないので、私は複製を削除するためにSQLクエリを使用して願っていないことを確認することができた。ここで

は、私の上記のクエリからの出力のうち印刷です:

---------------------------------------------------- 
|  did  | sensorid | timestamp | count | 
|"358188056470108"| 910 |1492487704000| 61 | 
|"358188056470108"| 910 |1492487705000| 61 | 
---------------------------------------------------- 

私はbigintまたは同様のパフォーマンスを向上させることができなかったことを知っているが、そうではない理由があります。

すべての複製を削除したいのですが、行の1つを保持することが重要です。理想的には、最も低い行の行が「元の」行idになります。

ここの誰かがこのようなクエリを作成するのに役立つことを願っています。

答えて

1

削除するには、IDを識別するために、ROW_NUMBER()とCTEを使用し、その後、(OPが離れて重複を伝えるために使用することができますユニークな `id`列を持っていません表示され、それらを

with CTE as 
(
select t1.*, row_number() over(partition by did, sensorid order by id) as rn 
from MyTable t1 
) 
delete 
from MyTable 
where id in (select id from CTE where rn > 1) 
+0

を削除またはランク付けする)。 (2番目のビューでは、彼はそれを持っているようですが、彼はそれをリストしません...) – wildplasser

+0

各行には一意のIDがあります。私はそれに言及するのを忘れたと思う。 id列はシリアル(自動的に整数を増やす) – Zeliax

関連する問題