テーブル作成時にインデックスとしてナンバリングしておけば違う書き方もできたんですけど、
特定の行だけで重複削除する方法はこれしか見つからなったので備忘録として記載。
最終的なコード
-- 一時テーブルの作成 ※1
CREATE TEMPORARY TABLE tmp AS
SELECT * FROM(
SELECT *, COUNT(column)over (PARTITION BY column ORDER BY column ROWS 3 PRECEDING) as count FROM `table`
) where count = 1;
-- テーブルのデータ削除 ※2
DELETE FROM `table` where true;
-- 一次テーブルから上記でデータ削除したテーブルへデータの追加 ※3
INSERT INTO `table` select EXCEPT(count) FROM tmp;
-- 一次テーブルの削除 ※4
DROP TABLE tmp;
一時テーブルの作成※1
SELECT *, COUNT(column)over (PARTITION BY column ORDER BY column ROWS 3 PRECEDING) as count FROM `table`
ここまでたどりつくのが長かった。
下記の記事を参考にしました。
分析関数(ウインドウ関数)をわかりやすく説明してみた
分析関数を使って重複していたらテーブルの上からいくつ重複しているかをカウントして「count」として列を作成
例えば下記のようなテーブルを作成して
CREATE TABLE `データセット名.test_orders` (fruits string);
insert into `データセット名.test_orders` select 'Apple';
insert into `データセット名.test_orders` select 'Apple';
insert into `データセット名.test_orders` select 'Apple';
insert into `データセット名.test_orders` select 'Apple';
insert into `データセット名.test_orders` select 'banana';
insert into `データセット名.test_orders` select 'banana';
下記を実行すると
SELECT *, COUNT(fruits)over (PARTITION BY fruits ORDER BY fruits ROWS 3 PRECEDING) as count FROM `Corporate_DataBase.test_orders`
下記の結果がでてきます。
ROWSの後ろの数値で前のいくつ前のレコードまで比較してカウントするかの設定が可能。
今回の場合2とか3にするとcountの結果が変わるので注意。
fruits | count |
---|---|
Apple | 1 |
Apple | 2 |
Apple | 3 |
Apple | 4 |
Banana | 1 |
Banana | 2 |
その結果からcountが1のレコードのみで一時テーブルを作成すると下記のコードになります。
CREATE TEMPORARY TABLE tmp AS
SELECT * FROM(
SELECT *, COUNT(column)over (PARTITION BY column ORDER BY column ROWS 3 PRECEDING) as count FROM `table`
) WHERE count = 1;
テーブルのデータ削除 ※2
DELETE FROM `table` where true;
一時テーブルを作成したら元のテーブルのデータを削除します。
一次テーブルから上記でデータ削除したテーブルへデータの追加 ※3
INSERT INTO `table` select EXCEPT(count) FROM tmp;
一時テーブルから元のテーブルへデータの以降。
※1で作成してしまったcountのカラム以外を
一時テーブルから※2で作成したテーブルへデータを移します。
一次テーブルの削除 ※4
DROP TABLE tmp;
一時テーブルの削除
これなくても良い気がするのですが、ないとエラーがでるので付けています。
4回もクエリ叩くの効率悪いなぁと思っているのでもっと良い方法があれば教えてほしいです。