Я хочу удалить повторяющиеся строки из таблицы measurement
в базе данных PostgreSQL 9.1.Удалить повторяющиеся строки ОШИБКА: дублировать значение ключа
Некоторые данные таблицы:
select column_name, data_type from information_schema.columns where table_name = 'measurement';
column_name | data_type
-------------+-----------
s_sum | real
s_l3 | real
s_l2 | real
s_l1 | real
q_sum | real
q_l3 | real
q_l2 | real
q_l1 | real
p_sum | real
p_l3 | real
p_l2 | real
p_l1 | real
irms_n | real
irms_l3 | real
irms_l2 | real
irms_l1 | real
urms_l3 | real
urms_l2 | real
urms_l1 | real
timestamp | integer
site | integer
id | integer
(22 rows)
и
select count(*) from measurement;
count
----------
56265678
(1 row)
Так что я хочу сделать, это удалить повторяющиеся строки, где все столбцы, кроме id
равны. Я пошел вперед и попробовал это с подходом в this answer.
SET temp_buffers = '1GB';
BEGIN;
CREATE TEMPORARY TABLE t_tmp AS
SELECT DISTINCT site,
timestamp,
urms_l1,
urms_l2,
urms_l3,
irms_l1,
irms_l2,
irms_l3,
irms_n,
p_l1,
p_l2,
p_l3,
p_sum,
q_l1,
q_l2,
q_l3,
q_sum,
s_l1,
s_l2,
s_l3,
s_sum
FROM measurement;
TRUNCATE measurement;
INSERT INTO measurement
SELECT * FROM t_tmp;
COMMIT;
где эхо/ошибка:
SET
BEGIN
SELECT 56103537
TRUNCATE TABLE
ERROR: duplicate key value violates unique constraint "measurement_pkey"
DETAIL: Key (id)=(1) already exists.
ROLLBACK
так это выглядит, как будто это было бы удалить дубликаты в порядке (сравните с количеством строк исходной таблицы measurement
выше), но тогда основным ограничением ключа нарушается. Я действительно не знаю, что происходит здесь, я полагаю, что INSERT
не работает на укороченной столе ...
Update:
Запрашиваемый SQL схема выглядит следующим образом:
--
-- PostgreSQL database dump
--
SET statement_timeout = 0;
SET client_encoding = 'UTF8';
SET standard_conforming_strings = on;
SET check_function_bodies = false;
SET client_min_messages = warning;
--
-- Name: plpgsql; Type: EXTENSION; Schema: -; Owner: -
--
CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;
--
-- Name: EXTENSION plpgsql; Type: COMMENT; Schema: -; Owner: -
--
COMMENT ON EXTENSION plpgsql IS 'PL/pgSQL procedural language';
SET search_path = public, pg_catalog;
SET default_tablespace = '';
SET default_with_oids = false;
--
-- Name: measurement; Type: TABLE; Schema: public; Owner: -; Tablespace:
--
CREATE TABLE measurement (
id integer NOT NULL,
site integer,
"timestamp" integer,
urms_l1 real,
urms_l2 real,
urms_l3 real,
irms_l1 real,
irms_l2 real,
irms_l3 real,
irms_n real,
p_l1 real,
p_l2 real,
p_l3 real,
p_sum real,
q_l1 real,
q_l2 real,
q_l3 real,
q_sum real,
s_l1 real,
s_l2 real,
s_l3 real,
s_sum real
);
--
-- Name: measurement_pkey; Type: CONSTRAINT; Schema: public; Owner: -; Tablespace:
--
ALTER TABLE ONLY measurement
ADD CONSTRAINT measurement_pkey PRIMARY KEY (id);
--
-- Name: public; Type: ACL; Schema: -; Owner: -
--
REVOKE ALL ON SCHEMA public FROM PUBLIC;
REVOKE ALL ON SCHEMA public FROM postgres;
GRANT ALL ON SCHEMA public TO postgres;
GRANT ALL ON SCHEMA public TO PUBLIC;
--
-- PostgreSQL database dump complete
--
А потом
SELECT id
FROM measurement
GROUP BY id
HAVING COUNT(*) > 1;
дает
id
----
(0 rows)
Поскольку вы не указываете столбцы для предложения 'insert', вы помещаете значение столбца' site' из таблицы tmp в таблицу измерений. Если вы укажете столбцы в инструкции 'insert':' insert into measurement (site, ....) select ... from t_tmp', вы получите другую ошибку, потому что вы не укажете значение для ' id', и он также не имеет значения по умолчанию. Это очень хороший пример, почему вы никогда не должны использовать 'insert' без указания столбцов и почему вы никогда не должны использовать' select * '- ваши столбцы просто не соответствуют –
@a_horse_with_no_name: Спасибо, что указали это. Он работал с использованием 'SELECT DISTINCT ON () FROM measurement'. FWIW, если вы ответите правильно, я приму это. –
phaebz