не работает delete с подзапросом на эту же таблицу

Запросы, планы, оптимизация запросов, ...

Модераторы: kdv, CyberMax

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

не работает delete с подзапросом на эту же таблицу

Сообщение KSilver » 08 авг 2006, 10:05

Код: Выделить всё

select
    id,
    id_reorg,
    numreg
from
    reorg1
where
    id_reorg in (select distinct(r1.id_reorg) from reorg1 r1 where r1.numreg = '137011294')
- выдает 6 записей
ID ID_REORG NUMREG
352 1000010680 137020336
355 1000010680 137020343
354 1000010680 137020350
353 1000010680 137011294
6447 1000013728 137007100
6446 1000013728 137011294

а запрос

Код: Выделить всё

delete from
    reorg1
where
    id_reorg in (select distinct(r1.id_reorg) from reorg1 r1 where r1.numreg = '137011294')
удаляет только 4

остаются нетронутыми записи
354 1000010680 137020350
6447 1000013728 137007100

хотя явный

Код: Выделить всё

delete from
    reorg1
where
    id_reorg in (1000010680, 1000013728)
удаляет все 6 записей

база диалект 1
FB 1.0
ps пробовал на FB 1.5, так там вообще только 3 записи удаляются

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 08 авг 2006, 10:38

Код: Выделить всё

select id, id_reorg, numreg from reorg1 where id_reorg in 
(select distinct(r1.id_reorg) from reorg1 r1 where r1.numreg = '137011294') 
Будь проще, и люди у тебе потянутся. :)

Код: Выделить всё

select r1.id, r1.id_reorg, r1.numreg from reorg r1 where r1.numreg = '137011294' 
C delete аналогично.
Если нет разницы, зачем платить больше?

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

Сообщение KSilver » 08 авг 2006, 10:42

Код: Выделить всё

select r1.id, r1.id_reorg, r1.numreg from reorg r1 where r1.numreg = '137011294'
выдаст только 2 записи
353, 6446
Ivan_Pisarevsky невнимательно просмотрели код :wink:

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 08 авг 2006, 11:12

Не подтверждаю.
Создал табличку, вписал эти шесть записей. И указанный тобой селект возвращает все 6, и делит убивает тоже 6.
Dialect 1, FB 1.0.3

Это у тебя настоящий запрос, который пользуешь, без упрощения?

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

Сообщение KSilver » 08 авг 2006, 12:27

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

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 08 авг 2006, 12:31

KSilver писал(а):

Код: Выделить всё

select r1.id, r1.id_reorg, r1.numreg from reorg r1 where r1.numreg = '137011294'
выдаст только 2 записи
353, 6446
Ivan_Pisarevsky невнимательно просмотрели код :wink:
Ладно, уговорил :) был невнимателен, просто всякие подзапросы с дистинктами наводят на мысли нехорошие о компетентности вопрошающего... :oops:

Что мешает подойти к вопросу традиционно, через джойны?

Код: Выделить всё

select 
  r1.id, 
  r1.id_reorg, 
  r1.numreg
from reorg1 r1 join reorg1 r2 on r1.id_reorg = r2.id_reorg 
  and r2.numreg = '137011294'

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

Сообщение KSilver » 08 авг 2006, 12:37

так select то работает нормально.
с delete вот проблемы, не удалянт все что нужно, а только часть.
Ivan_Pisarevsky читаем еще раз внимательно первый пост :wink:

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 08 авг 2006, 12:59

А и не будет оно нормально работать. Надо умертвлять (буферизовать) внутренний запрос. Я не помню: у нас ORDER BY в подзапросах позволяется? Вроде бы да, специально для FIRST-SKIP. Во-общем, надо добиться чтобы в в его плане был SORT, тогда отработает нормально.
PS: Oops, сейчас заметил Fb1. Плохо. Придется обертывать в процедуру.
Последний раз редактировалось Dimitry Sibiryakov 08 авг 2006, 13:03, всего редактировалось 1 раз.

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 08 авг 2006, 12:59

KSilver писал(а):так select то работает нормально.
с delete вот проблемы, не удалянт все что нужно, а только часть.
Ivan_Pisarevsky читаем еще раз внимательно первый пост :wink:
ОК, перечитал, как не нравился мне твой селект, так и не нравится. Запустил ибэксперт, забил твои данные, твои запросы, отрабатывает так как тебе хочется, т.е. глюк не воспроизводится, 6 записей отбирается, 6 записей удаляется. Проверил и запрос с джойнами, то же самое 6х6.
Хотя что-то подсознательно мне во всем этом не нравится...

ЗЫ фб 1.5.2

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 08 авг 2006, 13:05

Ivan_Pisarevsky писал(а):Запустил ибэксперт, забил твои данные, твои запросы, отрабатывает так как тебе хочется, т.е. глюк не воспроизводится, 6 записей отбирается, 6 записей удаляется.
У тебя нет индекса на id_reorg, а Серебрянному не повезло.

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

Сообщение KSilver » 08 авг 2006, 13:13

Dimitry Sibiryakov писал(а): У тебя нет индекса на id_reorg, а Серебрянному не повезло.
у меня и без индекса то же самое - пробовал сегодня.

Plan
PLAN SORT ((R1 NATURAL))
PLAN (REORG1 NATURAL)
Adapted Plan
PLAN SORT ((R1 NATURAL)) PLAN (REORG1 NATURAL)

4 record(s) was(were) deleted from REORG1


ORDER BY - в подзапросе не хочет работать :(
каким способом можго добится SORT ?

WildSery
Заслуженный разработчик
Сообщения: 1738
Зарегистрирован: 05 июн 2006, 16:19

Сообщение WildSery » 08 авг 2006, 13:14

2 KSilver:
Напиши DDL таблицы-то. А то непонятно что сравниваем. Я вот сперва все поля Integer объявил, пока не увидел, что numreg у тебя строковое...

И, кстати, из чего выполнение запроса тестируешь? IBExpert?

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 08 авг 2006, 13:24

Да, индексов нету.

А может ну его нафиг этот дистинг с позапросами?
1.

Код: Выделить всё

select id, id_reorg, numreg
from reorg1 r1 join reorg1 r2 on r1.id_reorg = r2.id_reorg and r2.numreg = '137011294'
2.

Код: Выделить всё

delete from reorg1 r3
where id in(select r1.id
from reorg1 r1 join reorg1 r2 on r1.id_reorg = r2.id_reorg and r2.numreg = '137011294')

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

Сообщение KSilver » 08 авг 2006, 13:28

Код: Выделить всё

CREATE TABLE REORG1 (
    ID        INTEGER NOT NULL,
    ID_REORG  INTEGER,
    NUMREG    CHAR(9) CHARACTER SET NONE
);
Тестирую из IBExpert, проверил сейчас на IBConsole - то же самое.

[Модератор: юзай тег Code]

Dimitry Sibiryakov
Заслуженный разработчик
Сообщения: 1436
Зарегистрирован: 15 сен 2005, 09:05

Сообщение Dimitry Sibiryakov » 08 авг 2006, 13:38

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

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

Сообщение KSilver » 08 авг 2006, 13:39

Ivan_Pisarevsky

Код: Выделить всё

select r1.id
from reorg1 r1 join reorg1 r2 on r1.id_reorg = r2.id_reorg and r2.numreg = '137011294'
возвращает все 6 ID
но

Код: Выделить всё

delete from reorg1 r3
where id in(select r1.id
from reorg1 r1 join reorg1 r2 on r1.id_reorg = r2.id_reorg and r2.numreg = '137011294')
удаляет все только те же 4 записи.

Andrew Sagulin
- что-то вроде проясняется, но неужели так и есть ?

Ivan_Pisarevsky
Заслуженный разработчик
Сообщения: 644
Зарегистрирован: 15 фев 2005, 11:34

Сообщение Ivan_Pisarevsky » 08 авг 2006, 13:42

Плюнь на запрос, пиши ХП.

Не зря не люблю селект с делетом по одной таблице... нутром чую глюки будут, потому так не делал никогда.

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

Сообщение KSilver » 08 авг 2006, 13:42

уважаемый модератор вы наверное случайно удалили оч ценный пост
Andrew Sagulin

Andrew Sagulin
Сообщения: 53
Зарегистрирован: 11 мар 2005, 15:44

Сообщение Andrew Sagulin » 08 авг 2006, 13:43

Dimitry Sibiryakov писал(а):А и не будет оно нормально работать.
Поправьте, Дмитрий, если я не прав.
Подзапрос выполняется для каждой удаляемой записи. В результате, строка "353 1000010680 137011294" может быть удалена раньше, чем другие строки с ID_REORG=1000010680, т.е. результат зависит от физического порядка записей в таблице. Поэтому нужно однократное выполнение подзапроса с его материализацией, а FB этого не умеет (?).

Прошу прощения: сначала отправил сообщение, потом подумал, что бред - удалил. Потом всё-таки решил, что не бред и восстановил. :oops:
Последний раз редактировалось Andrew Sagulin 08 авг 2006, 13:49, всего редактировалось 1 раз.

KSilver
Сообщения: 17
Зарегистрирован: 22 май 2006, 15:03

Сообщение KSilver » 08 авг 2006, 13:45

Ivan_Pisarevsky придется поколдовать с ХП
Всем BIG THANKS за участие.

Ответить