Пометить дубликаты : как победить коррелированные запросы?

Varan
Дата: 25.05.2004 13:08:02
Я со своими Update-ами уже весь форум замучил.
Желаю разобраться с коррелированными запросами раз и навсегда. Не далее как вчера была похожая тема Саныча. Но чего-то я в этом вопросе недопонимаю, и каждый раз когда я с этим сталкиваюсь, я убеждаюсь, что я ничего не понимаю. Посему вопрос к тем, кто в этом разбирается - как надо рассуждать при написании коррелированного запроса. И пример задачи, которую я не могу решить (:-()
В таблицу test
id	FK	duplicate
1	1	Нет
2	1	Да
3	2	Нет
4	2	Да
5	1	Да
6	1	Нет
7	5	Нет
8	1	Нет
9	5	Нет
10	2	Нет
начиная с какой-то известной строки вставляются данные ( в данном примере с 6). После вставки надо проставить в поле duplicate флаг в те строки, которые уже проходили ранее по данному FK, т.е в данном примере флаг должен проставиться в соотв. поле строк с id=6,8,9,10
Если кто-то решит эту задачку, большая просьба разъяснить, как этот запрос работает, чтоб разобраться с этим раз и навсегда.
Может еще и ссылку кто даст, где про такие запросы можно почитать.
Спасибо.
Отключаюсь на 2 часа.
Bely
Дата: 25.05.2004 13:17:03
Я вот условия не очень понял...
автор
После вставки надо проставить в поле duplicate флаг в те строки, которые уже проходили ранее по данному FK

Объясни по человечески - это значит, что надо Update-нуть только те строки у которых FK такой-же как и у 6-й строки?
тогда почему такой список... id=6,8,9,10

не догоняю...
paparome
Дата: 25.05.2004 13:19:08
ИМХО

Имеется ввиду следующие

Если есть в таблице записи с id меньшим текущей и с равным FK, то ставм "ДА", иначе "НЕТ"

Так понятно?
paparome
Дата: 25.05.2004 13:23:06
Update test t1 left join test t2 on (t1.id > t2.id) and (t1.fk = t2.fk)
set t1.b = true
where t2.id is not null;

проверил - работает :)
Varan
Дата: 25.05.2004 15:14:46
Bely.
paparome очень точно выразил мысль : "Если есть в таблице записи с id меньшим текущей и с равным FK, то ставм "ДА", иначе "НЕТ"
Paramone, красота, действительно этот запрос
Update test t1 left join test t2 on (t1.id > t2.id) and (t1.fk = t2.fk)
set t1.duplicate = true
where t2.id is not null;
работает.
Вот только я, жертва графических конструкторов запросов, не понимаю - как. И не понимаю, как надо думать, чтобы его придумать. Если есть у тебя время, объясни, пожалуйста, словами, как он работает и как вообще делать эти коррелированные запросы. Как ты при этом рассуждаешь?
(c)VIG
Дата: 25.05.2004 15:19:49
Мысли в слух :)
1)Непонятно, зачем держать дополнительно поле в таблице ( в данном случае -duplicate),не несущее самостоятельного смысла, когда всегда можно получить нужное значение простым (или не очень ) селектом.
2)Если уж возникла крайняя необходимость в таком поле , то лучше его инициализировать во время вставки данных, а не морочить голову апдейтами .
paparome
Дата: 25.05.2004 15:28:44
автор
Вот только я, жертва графических конструкторов запросов, не понимаю - как.


Не пользуйся графическими конструкторами:
- Сначала будет тяжело
- Зато потом, просто (я, например, уже не могу в конструкторе нарисовать, что-то сложнее select * from tbl1 :( )

автор
И не понимаю, как надо думать, чтобы его придумать.

Я тоже плохо понимаю, как надо думать, чтобы такое придумать :(
Вот, например, если в этом запросе поменять left join на inner join, то наверное он не будет работать, а может будет (ну не знаю я :( )

А, вообще, примерно так - выражаешь свою мысль на русском, а потом переводишь в SQL (у меня так)
Вот я написал (достаточно точно сформулировал суть поблемы)
автор
Если есть в таблице записи с id меньшим текущей и с равным FK, то ставм "ДА", иначе "НЕТ"

И перевел это на SQL:
Если есть в таблице записи с id меньшим текущей = (t1.id > t2.id)
и = and
с равным FK = (t1.fk = t2.fk)
то ставм "ДА" = Set t1.duplicate = true

кстати - если left заменить на inner, то наверное быстрее будет и условие не потребуется :) (хотя могет и ругнуться, что запрос не обновляемый :( )

автор
и как вообще делать эти коррелированные запросы.

коррелированные - я и словьев-то таких не знаю :(
(c)VIG
Дата: 25.05.2004 15:39:43
2 Varan
Представь ,что коррелированный запрос - это некая функция ,получающая входные параметры от основного запроса ,и возвращающая результаты работа в основной запрос.
Varan
Дата: 25.05.2004 15:44:45
VIG,
Ну, этот "duplicate" не мною придуман, смысл, видимо, в нем есть, хотя, может быть ту же мысль можно и в другой структуре воплотить. Смысл в том, что надо быстро знать, прервая это строка по данному FK или нет. В тех запросах, где эта структура используется, нет возможности это проверять запросом (они и так на пределе), лучше это просто прочитать.
Можно, наверное, и при вставке (кстати, как?), но мне это что-то в последий момент в голову пришло. Но по смыслу будет почти то же самое, что Paramone предложил.
Блин, их же при удалении придется апдейтить еще...:-(. У меня это как-то из головы вылетело.
paparome
Дата: 25.05.2004 15:48:40
2 Варан

Да - все глухо :(

А зачем, что-то там запросом насчитывать?

Там где надо проверить, первая это запись или нет пишешь
(DCount("*","test","(id <" & rs("id") & ") and (fk = " & rs("fk") & ")")>0)
Вот и будут твои ДА и НЕТ, только в реальном времени!