Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Вопрос по SQL


Pk ©   (2003-02-06 13:27:00) 

Есть таблица, состоящая из 4 полей. Первые 2 поля должны быть уникальны но в базе не было введено ограничение на уникальность в результате появились записи в которых комбинация из этих 2 полей повторяется. Так вот, как выбрать нужные записи или удалить лишние?


Danilka   (2003-02-06 15:37:00) [1]

Pk (06.02.03 15:34)
я давал ссылку.
там есть решение для орокла, с минусом, оно шерстило таблицу в полтора миллиона записей за 35 сек.

я для себя раньше решал это проблему по-тупому, без ровид.
мое решение тоже есть в этой ссылке.
оно, подойдет для любой бд, даже для той, у которой нет уникального ровид.


Pk   (2003-02-06 15:34:00) [2]

minus проблему не решал. select Field1, Field2 from T1 minus select distinct Field1, Field2 from T1 не возвращал ни 1 строчки.


Danilka   (2003-02-06 15:14:00) [3]

sniknik © (06.02.03 14:54)
в орокле еще и очень быстрый minus есть :))


sniknik   (2003-02-06 14:54:00) [4]

если > (Oracle) и там есть rowid то и вводить уника не не понадобится, есть.

предупреждать надо какая база.


stone   (2003-02-06 14:53:00) [5]


> delete from TableName from TableName h where exists (select
> ctlg_no from TableName where key1 = h.key1 and key2 = h.key2
> and tmp_id > h.tmp_id)

копировал из своего действующего запроса не все переделал..

alter table TableName add tmp_id integer IDENTITY(1,1)

delete from TableName from TableName h where exists (select * from TableName where key1 = h.key1 and key2 = h.key2 and tmp_id > h.tmp_id)


stone   (2003-02-06 14:52:00) [6]


> надо модифицировать, ввести (временно) 1 действительно уникальное
> поле и в условие уже ставить его

Совершенно верно. Добавить автоинкрементное поле.

alter table TableName add tmp_id integer IDENTITY(1,1)

delete from TableName from TableName h where exists (select ctlg_no from TableName where key1 = h.key1 and key2 = h.key2 and tmp_id > h.tmp_id)


Danilka   (2003-02-06 14:44:00) [7]

вот здесь:
http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1043925029&n=1

есть красивое решение.


Pk   (2003-02-06 14:38:00) [8]


DarkGreen © (06.02.03 13:50)

select Field1, Field2, Count(Field1), Count(Field2) from T1
where (Count(Field1) > 1) and (Count(Field2) > 1)
group by Field1, Field2

Ошибка: "Недопустимая смесь функций и колонок" (Oracle)


sniknik   (2003-02-06 14:34:00) [9]

нет не единственный, просто в самом запросе глючок.

SELECT DISTINCT id FROM Table1
дает действительно уникальную (обрезанную) линейку значений.
а вот условие
WHERE id IN, выбирает всезаписи которые есть в выбранной линейке, в том числе и повтор.

надо модифицировать, ввести (временно) 1 действительноуникальное поле и в условие уже ставить его.


Reindeer Moss Eater   (2003-02-06 14:30:00) [10]

Delete From table Where Первичный_Ключ not in (select MAX(Первичный_Ключ) from Table Group By Поле1, Поле2 )


DarkGreen   (2003-02-06 14:28:00) [11]

То что я предложил ты похоже не смотрел?


stone   (2003-02-06 14:21:00) [12]


> и вправду всех выбирает (что показал приведенный пример).
> В некоторых записях есть действительно повторение по всем
> полям но в некоторых повторяются только 2 ключевых.


Тогда единственный способ проехать курсором, вопрос только в том какие записи из дубликатов оставить, а какие удалить. При полном соответствии - все ясно, а при частичном - решать вам.


Pk   (2003-02-06 14:14:00) [13]


> SELECT * FROM Table1 WHERE id1*1000+id2 IN (SELECT DISTINCT
> id1*1000+id2 FROM Table1)

- возвращает всю таблицу

> так все равно всех выберет

и вправду всех выбирает (что показал приведенный пример). В некоторых записях есть действительно повторение по всем полям но в некоторых повторяются только 2 ключевых.


sniknik   (2003-02-06 13:56:00) [14]

я бы сделал просто, так
SELECT * FROM Table1 WHERE id1*1000+id2 IN (SELECT DISTINCT id1*1000+id2 FROM Table1)

естественно 1000 может мало, а посмотреть на твою таблицу не могу, выдымывай сам.


stone   (2003-02-06 13:53:00) [15]


> SELECT * FROM Table1 WHERE (id1,id2) IN (SELECT DISTINCT
> id1,id2 FROM Table1).

так все равно всех выберет

тут важно знать возможны ли поторения значений во всех черырех полях одновременно? Если нет. Будем анализировать дальше.


DarkGreen   (2003-02-06 13:50:00) [16]

Так что ли?
select Field1, Field2, Count(Field1) Count(Field2)
where (Count(Field1) > 1) and (Count(Field2) > 1)
group by Field1, Field2


Pk   (2003-02-06 13:46:00) [17]


> если дублирование по 1 полю смотреть то примерно
> SELECT * FROM Table1 WHERE id IN (SELECT DISTINCT id FROM
> Table1)


а мне нужно исключить дублирование по 2 полям. Что то типа SELECT * FROM Table1 WHERE (id1,id2) IN (SELECT DISTINCT id1,id2 FROM Table1).


sniknik   (2003-02-06 13:42:00) [18]

SELECT DISTINCT .... выбрать, и удалить также можно SELECT * INTO FROM SELECT DISTINCT ...., исходную удалить а получившуюся переименовать.

а вообще смотря как решать какие "нужные" а какие "лишние". DISTINCT кстати полное совпадения строк убирает, если дублирование по 1 полю смотреть то примерно
SELECT * FROM Table1 WHERE id IN (SELECT DISTINCT id FROM Table1)
и т.д.


Наверх

Титульная страница Поиск, карта сайта Написать письмо