Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Firebird, Interbase > удаление всех дубликатов из таблицы


Автор: ksili 24.5.2007, 06:50
Есть таблица в которой встречаются записи полностью идентичные, кроме ключевого поля. необходимо удалить дубликаты, оставив только по одной копии, чтобы не было повторений.
Таблица такая:
Код

CREATE TABLE T_MG_CODE (
    ID_MG_CODE          INTEGER NOT NULL,
    CODE                CHAR(15) NOT NULL,
    MG_ACTIVE           CHAR(1) NOT NULL,
    PRICE               NUMERIC(15,2) NOT NULL,
    ID_CHANEL           CHAR(1),
    NEW_DISP_ID_CHANEL  CHAR(1),
    PRICE_IN            NUMERIC(15,2),
    COMMENT             CHAR(50),
    ID_DIAL_PLAN        INTEGER,
    DIGITS_TOTAL        INTEGER,
    PRICE_LG            NUMERIC(15,2) NOT NULL,
    PRICE_SLG           NUMERIC(15,2) NOT NULL
);

ALTER TABLE T_MG_CODE ADD CONSTRAINT PK_T_MG_CODE PRIMARY KEY (ID_MG_CODE);

Сделал такую хранимку:
Код

begin
  --выбираем записи с одинаковым полем CODE
  for select count(ID_MG_CODE),min(ID_MG_CODE),CODE from t_mg_code
  where MG_ACTIVE='1'
  group by CODE
  into :var_count,:var_id,:var_code
  do
  begin
  --если записей с таким кодом было несколько, удаляем дубликаты
  if(var_count>1) then
    begin
        --выбираем все поля записи с текущим кодом
        select PRICE,ID_CHANEL,NEW_DISP_ID_CHANEL,comment,
        ID_DIAL_PLAN,DIGITS_TOTAL,PRICE_LG,PRICE_SLG
        from t_mg_code
        where ID_MG_CODE=:var_id
        into :var_p1,:var_ch,:var_newd,:var_com,:var_idp,
        :var_digits,:var_p2,:var_p3;
        --удаляем записи, где такие же значения полей, но другой первичный ключ
        delete from t_mg_code
        where (MG_ACTIVE='1' and ID_MG_CODE<>:var_code and CODE=:var_code
        and PRICE=:var_p1 and ID_CHANEL=:var_ch and NEW_DISP_ID_CHANEL=:var_newd
        and comment=:var_com and ID_DIAL_PLAN=:var_idp and DIGITS_TOTAL=:var_digits
        and PRICE_LG=:var_p2 and PRICE_SLG=:var_p3);
    end
  end
  suspend;
end

Она компилируется без ошибок. Но прежде, чем её запускать, хотел бы спросить у знатоков, нет ли тут каких-нибудь грубых ошибок. А-то таблица T_MG_CODE большая и если что не так, трудно будет разобраться.

Напрягает ещё то, что IB Expert выделяет жирным поле COMMENT как будто это команда или служебное слово, хотя это имя поля и раньше при работе с ним никаких проблем не возникало.

Автор: ksili 24.5.2007, 11:29
Процедура оказалась неправильная. Она сравнивает все записи с одинаковым полем CODE только с тем из них, которого ID_MG_CODE минимальный, а надо по идее, чтобы каждый с каждым сравнивался

Автор: ksili 24.5.2007, 12:51
Ура! Всё получилось! Совсем по-другому и вроде даже проще всё выглядеть стало

Автор: Deniz 25.5.2007, 05:52
Можно одним запросом, например удаляем все повторения CODE:
Код

delete from test t1
where exists
(
  select count(t2.id)
    from test t2
    where (t2.code = t1.code)
    group by t2.code
    having count(t2.id) > 1
)

если полей для сравнение больше, надо их добавить в where (t2.code = t1.code) and (...) and (...)

Автор: ksili 25.5.2007, 06:12
По-моему этот запрос удалит все повторяющиеся записи, а не все повторения. т.е. ни одной копии не оставит. хотя я не проверял

Автор: Deniz 25.5.2007, 13:52
А что мешает проверить?
Если знаешь как работает InterBase и клоны в таких ситуациях, не будешь так говорить.

Автор: skeef 8.5.2010, 17:51
А так не проще?

Код


DELETE FROM TABLE a, TABLE b
WHERE  (a.FIELD1 = b.FIELD1)  AND 
             (a.FIELD2 = b.FIELD2) AND
             (a.FIELD3 = b.FIELD3) AND
             (a.ID > b.ID) 



и работает гораздо быстрее

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)