Модераторы: Akella
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Удаление дубликатов, помощь в создании запроса 
V
    Опции темы
Akella
Дата 15.12.2006, 10:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



В базе есть 2 связанные таблицы.

user posted image

Проблема в том, что хочу составить запрос, который удалит дубликаты из левой таблицы.
Нужно удалить все названия "Аверс", оставить только одну любую запись, не важно какую. Все телефоны из правой таблицы, которые на всех удаляемых  "Аверс`ах" перенести на ту, запись, которую оставляем.

Таких повторений много, поэтому нужно это сделать в цикле, в хранимке.

Левая таблица
Код

CREATE TABLE MEDIATORS (
    ID           "INT" NOT NULL /* "INT" = INTEGER CHECK ((VALUE >= 0) or (VALUE is NULL) or (VALUE = -1)) */,
    NAME         STRING50 /* STRING50 = VARCHAR(50) */,
    EXP          BOOL COLLATE PXW_CYRL /* BOOL = VARCHAR(1) DEFAULT 'T' */,
    DELETED      BOOL COLLATE PXW_CYRL /* BOOL = VARCHAR(1) DEFAULT 'T' */,
    PHONES_LIST  COMPUTED BY ((select TELS_LIST from SP_TELS_LIST_MEDIATORS(MEDIATORS.ID))),
    UID          "INT" /* "INT" = INTEGER CHECK ((VALUE >= 0) or (VALUE is NULL) or (VALUE = -1)) */,
    ID_TYPE      "INT" /* "INT" = INTEGER CHECK ((VALUE >= 0) or (VALUE is NULL) or (VALUE = -1)) */
);


Правая таблица
Код

CREATE TABLE PHONES (
    ID           "INT" NOT NULL /* "INT" = INTEGER CHECK ((VALUE >= 0) or (VALUE is NULL) or (VALUE = -1)) */,
    TEL          STRING20 NOT NULL COLLATE PXW_CYRL /* STRING20 = VARCHAR(20) */,
    ID_APART     "INT" /* "INT" = INTEGER CHECK ((VALUE >= 0) or (VALUE is NULL) or (VALUE = -1)) */,
    ID_ARENDA    "INT" /* "INT" = INTEGER CHECK ((VALUE >= 0) or (VALUE is NULL) or (VALUE = -1)) */,
    ID_OFF       "INT" /* "INT" = INTEGER CHECK ((VALUE >= 0) or (VALUE is NULL) or (VALUE = -1)) */,
    ID_MEDIATOR  "INT" /* "INT" = INTEGER CHECK ((VALUE >= 0) or (VALUE is NULL) or (VALUE = -1)) */,
    EXP          BOOL COLLATE PXW_CYRL /* BOOL = VARCHAR(1) DEFAULT 'T' */
);


Таблицы связаны по ключу. Как видно из скриптов, по полям PHONES.ID_MEDIATOR и MEDIATORS.ID
PM MAIL   Вверх
Romkin
Дата 15.12.2006, 11:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 14.11.2006
Где: Москва

Репутация: 1
Всего: 5



1. for select Посредники, min(ID) 
2. в цикле update для телефонов set ID = <minID> где их ID in (select ID from Посредники where Посредник = <переменная>)
3. все, осталось удалить дублирующихся посредников. Примеры запросов есть на ibase.ru
Так достаточно? smile
PM ICQ   Вверх
Akella
Дата 15.12.2006, 12:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



наверное

Добавлено @ 12:22 
вроде оно
Код

begin
 for select Min(m.ID) from MEDIATORS m
 group by m.name
 into :NEW_VAR
 do begin
   update PHONES p
   set p.ID_MEDIATOR = :NEW_VAR where p.ID_MEDIATOR in (select m.ID from MEDIATORS M where m.ID = :NEW_VAR);

 end
end


Это сообщение отредактировал(а) Akella - 15.12.2006, 12:32
PM MAIL   Вверх
Akella
Дата 15.12.2006, 12:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



не, Romkin, ты не прав

хотябы вот этим

Цитата(Romkin @  15.12.2006,  11:12 Найти цитируемый пост)
for select Посредники, min(ID) 


PM MAIL   Вверх
Romkin
Дата 15.12.2006, 13:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 189
Регистрация: 14.11.2006
Где: Москва

Репутация: 1
Всего: 5



Почему? Это ты неизвестно чего делаешь своим запросом smile 
Поле обновляешь тем же значением  smile 
Код

update PHONES p    
   set p.ID_MEDIATOR = :NEW_VAR where p.ID_MEDIATOR in (select m.ID from MEDIATORS M where m.ID = :NEW_VAR);

Подзапрос возвращает четко только значения NEW_VAR smile 

Вот так примерно должно быть:
Код

begin    
 for select m.name, Min(m.ID) from MEDIATORS m    
 group by m.name    
 into :NAME, :NEW_VAR    
 do begin    
  --Переделываем ID на одно имя с наименьшим ID
   update PHONES p    
   set p.ID_MEDIATOR = :NEW_VAR where p.ID_MEDIATOR in (select m.ID from MEDIATORS M where m.name = :NAME);
  --удаляем все одинаковые имена с другими ID
  delete from MEDIATORS
  where name = :NAME and ID <> :NEW_VAR;    
 end    
end

Советую индексировать m.name - будет быстрее
PM ICQ   Вверх
Akella
Дата 15.12.2006, 14:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Творец
****


Профиль
Группа: Модератор
Сообщений: 18485
Регистрация: 14.5.2003
Где: Корусант

Репутация: 20
Всего: 329



    спасибо, с меня +
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Interbase"
Alex

Обязательно указание:

1. Версию InterBase (Firebird, Yaffil)

2. Способа доступа (ADO, BDE, IBX и т.д.)

  • КАК ПРАВИЛЬНО ОФОРМИТЬ КОД - ЗДЕСЬ
  • КАК ПРАВИЛЬНО УКАЗАТЬ ТЕКСТ ОШИБКИ - ЗДЕСЬ
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • FAQ раздела лежит здесь!

Если Вам понравилась атмосфера форума, заходите к нам чаще! С Уважением, Akella.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Firebird, Interbase | Следующая тема »


 




[ Время генерации скрипта: 0.1305 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.