1

(PROPERTY_ID, GPSTIME, STATION_ID, PROPERTY_TYPE, VALUE)PROPERTY_ID が主キーで STATION_ID が外部キーのような列を持つテーブルがあります。

このテーブルは、状態の変化を記録します。各行は、特定の時間におけるステーションのプロパティ値を表します。ただし、そのデータは、各プロパティが列 (のような(STATION_ID, GPSTIME, PROPERTY1, PROPERTY2, PROPERTY3, ...)) であった古いテーブルから変換されました。通常、一度に変更されるプロパティは 1 つだけなので、多くの重複があります。

同じ値を持つ連続するすべての行を削除する必要があります。

例。古いテーブルには次のような値が含まれていました

time  stn   prop1  prop2
100   7     red    large
101   7     red    small
102   7     blue   small
103   7     red    small

変換されたテーブルは

(order by time,type)          (order by type,time)
time  stn type  value         time  stn type value
100   7   1     red           100   7   1    red
100   7   2     large         101   7   1    red
101   7   1     red           102   7   1    blue
101   7   2     small         103   7   1    red
102   7   1     blue          100   7   2    large
102   7   2     small         101   7   2    small
103   7   1     red           102   7   2    small
103   7   2     small         103   7   2    small

に変更する必要があります

time  stn type  value
100   7   1     red
100   7   2     large
101   7   2     small
102   7   1     blue
103   7   1     red

テーブルには約 2200 万行が含まれています。

私の現在のアプローチは、プロシージャを使用してテーブルを反復処理し、重複を削除することです。

BEGIN
    DECLARE done INT DEFAULT FALSE;
    DECLARE id INT;
    DECLARE psid,nsid INT DEFAULT null;
    DECLARE ptype,ntype INT DEFAULT null;
    DECLARE pvalue,nvalue VARCHAR(50) DEFAULT null;
    DECLARE cur CURSOR FOR 
        SELECT station_property_id,station_id,property_type,value 
        FROM station_property 
        ORDER BY station_id,property_type,gpstime;
    DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
    OPEN cur;
    read_loop: LOOP
        FETCH cur INTO id,nsid,ntype,nvalue;
        IF done THEN 
            LEAVE read_loop;
        END IF;        
        IF (psid = nsid and ptype = ntype and pvalue = nvalue) THEN
            delete from station_property where station_property_id=id;
        END IF;
        SET psid = nsid;
        SET ptype = ntype;
        SET pvalue = nvalue;
    END LOOP;
    CLOSE cur;
END

ただし、遅すぎます。20000 行のテスト テーブルでは、6 分間で 10000 の重複が削除されます。手順を最適化する方法はありますか?

PS私はまだ古いテーブルをそのまま持っているので、変換後に重複を処理するよりも、重複なしで変換してみる方が良いかもしれません。

アップデート。

どの重複を許可し、どれを許可しないかを明確にするため。

  1. プロパティが変更されてから元に戻る場合、最初と最後のレコードに同じ station_id、type、および value が含まれていても、3 つのレコードすべてを保存する必要があります。
  2. 同じ station_id、type、および value を持つ連続した (GPSTIME による) レコードが複数ある場合、最初のレコード (その値の変更を表す) のみを保存する必要があります。

つまり、a -> b -> b -> a -> aに最適化する必要がありますa -> b -> a

解決

@Kickstart が示唆したように、フィルタリングされたデータが入力された新しいテーブルを作成しました。前の行を参照するために、この質問で使用されているものと同様のアプローチを使用しました。

rename table station_property to station_property_old;
create table station_property like station_property_old;

set @lastsid=-1;
set @lasttype=-1;
set @lastvalue='';

INSERT INTO station_property(station_id,gpstime,property_type,value)
select newsid as station_id,gpstime,newtype as type,newvalue as value from
-- this subquery adds columns with previous values
    (select station_property_id,gpstime,@lastsid as lastsid,@lastsid:=station_id as newsid,
    @lasttype as lasttype,@lasttype:=property_type as newtype,
    @lastvalue as lastvalue,@lastvalue:=value as newvalue
    from station_property_old
    order by newsid,newtype,gpstime) sub
-- we filter the data, removing unnecessary duplicates
where lastvalue != newvalue or lastsid != newsid or lasttype != newtype;

drop table station_property_old;
4

2 に答える 2

1

場合によっては、GROUP BY を使用して既存のテーブルから選択された新しいテーブルを作成します。このようなもの(テストされていないため、タイプミスを許してください):-

INSERT INTO station_property_new
SELECT station_property_id, station_id, property_type, value 
FROM (SELECT station_property_id, station_id, property_type, value, COUNT(*) FROM station_property GROUP BY station_property_id, station_id, property_type, value) Sub1
于 2012-11-22T12:39:37.010 に答える
1

プロパティの連鎖に関して、ステーション/タイプ/値列の組み合わせが一意であることを保証するために一意の制約を設定できません。そうすれば、重複する値に変更できなくなります。

于 2012-11-22T13:07:49.537 に答える