Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > Запрос на удаление


Автор: Dynamic 21.4.2005, 14:52
Привет! Помогите написать запрос (BDE/Paradox):

есть таблица, типа

St_Id St_Name1 St_Name2 St_Name3 St_BirthDay St_DateVid

Код

1. Петров Иван Иванович 1963 1.01.2005
2. Петров Иван Иванович 1963 1.03.2003
3. Иванов Иван Петрович 1975 12.09.2002
4. Иванов Иван Петрович 1975 12.11.2005
5. Сидоров Николай Петрович 1987 1.04.2002


в таблице надо оставить только неповторяющиеся записи с максимальным значением Даты, т.е., чтобы получилось так:

Код

1. Петров Иван Иванович 1963 1.01.2005
4. Иванов Иван Петрович 1975 12.11.2005
5. Сидоров Николай Петрович 1987 1.04.2002


Выбрать такие записи получается, а вот правильно удалить - нет.
Так выбираю:

Код

select st_name1,st_name2,st_name3,st_birthday, max(st_datavid) as maxdate from strax
group by st_name1,st_name2,st_name3,st_birthday
having count(*)>1

Получается
Код

Петров Иван Иванович 1963 1.01.2005
Иванов Иван Петрович 1975 12.11.2005

Который час бьюсь
Заранее спасибо всем ответившим.

Автор: Негодяй 21.4.2005, 15:05
Цитата
having count(*)>1)


эх, подзабыл уже всё на фиг, но может в этом проблема? и есть заменитель вроде как этой операции просто запретить дублирование? а не как в твоём случае который машина понимает наверное как "именно опираясь на запрос, где больше 1 значит мне это и нужно"?

Автор: Dynamic 21.4.2005, 15:20
Смысл в том, что мне нужно профильтровать таблицу на наличие дубликатов записей о клиентах. Если клиент внесен один раз, то мы его пропускаем, если 2 и больше, то оставляем только того, у которого более поздняя дата St_DataVid, остальных удаляем.

После моего запроса в НД попадают как раз те данные, клиентов с которыми надо оставить. Но вот что делать дальше - ума не приложу. smile

Автор: Негодяй 21.4.2005, 15:39
Цитата
select * from
(select st_name1,st_name2,st_name3,st_birthday, max(st_datavid) from strax
group by st_name1,st_name2,st_name3,st_birthday
having count(*)>1)

а если сначала поудалять минимальные значения st_datavid (вместо max - min), цикл не заканчивать пока запрашиваемая запись (count) не будет равна 1;
затем повторить вышеописанный запрос без параметра having...?;

а если вместо всего так сделать having count(*)>=1?

Автор: Dynamic 21.4.2005, 16:04
Там в первом посте ошибочка закралась в текст запроса (от одного тестового прогона), уже убрал. Суть не меняется.
Цитата
having count(*)>=1

Тогда Having можно вообще убрать. Над остальным думаю...

Автор: Dimich 22.4.2005, 15:55
Тут видится следующая технология:
Код

delete strax where
(St_Name1, St_Name2, St_Name3, St_BirthDay, St_DateVid) not in
(
select st_name1,st_name2,st_name3,st_birthday, max(st_datavid) as maxdate from strax
group by st_name1,st_name2,st_name3,st_birthday
having count(*)>=1
)

Автор: Dynamic 22.4.2005, 17:27
Сдается мне, что производится попытка удаления ВСЕХ записей, КРОМЕ тех, что удовлетворяют выборке, т.е. и "одиночных" тоже.

Автор: Golden Hands 23.4.2005, 00:08
Почтенные, не мучайтесь.
Вот правильный Select (насколько я понял САБЖ):

Код

SELECT st_name1,st_name2,st_name3,st_birthday, max(st_datavid) as maxdate
From strax
Group By st_name1,st_name2,st_name3,st_birthday;


И, соответственно, Delete:

Код

Delete *
From  strax
where (St_Name1, St_Name2, St_Name3, St_BirthDay, St_DateVid) not in
(
SELECT st_name1,st_name2,st_name3,st_birthday, max(st_datavid) as maxdate
From strax
Group By st_name1,st_name2,st_name3,st_birthday
);

Автор: Dynamic 26.4.2005, 23:24
Да вроде пришли к мнению, что Парадокс не поддерживает вложенные селекты.

Автор: Golden Hands 26.4.2005, 23:44
И то правда, не поддерживает.
Вот, если интересно - http://forum.vingrad.ru/index.php?showtopic=14299

Автор: Dimich 27.4.2005, 07:19
Ну тогда только навигационным методом можно решить эту задачу, т.е. писать процедуру.

Автор: innok 28.4.2005, 14:43
решалась похожая проблема, т.е. надо было выбрать наименование организации с максимальной датой. Мож удастся приспособить:
Код

select N.Id, N.Wrkcode,  N.Wrkname,  (select max(I.Datechange)
from Nameorg I where (I.Wrkcode = N.Wrkcode)) as MAX_DATE
from Nameorg N where (N.Datechange = (select max(I.Datechange) 
from Nameorg I where (I.Wrkcode = N.Wrkcode)))
order by Wrkcode 



[code=delphi]

Автор: Dynamic 3.5.2005, 23:10
Цитата(Dimich @ 27.4.2005, 07:19)
Ну тогда только навигационным методом можно решить эту задачу, т.е. писать процедуру.

НаписАл уже (TQuery + TTable).

Автор: ТоляМБА 19.5.2005, 13:31
Есть вариант с исользованием только SQL (без TTable), правда придется создавать одну промежуточную таблицу. Если устраивает такой вариант - телеграфируй, напишу

Автор: Dynamic 19.5.2005, 20:57
Спасибо, уже не надо: я перевожу проект на FireBird, попытаюсь переделать сабж через вложенные select'ы, как мне подсказывали http://forum.sources.ru/index.php?showtopic=92009&hl=Запрос%20на%20удаление&st=19

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