Форум: "Базы";
Текущий архив: 2003.07.28;
Скачать: [xml.tar.bz2];
Вниз[Oracle] вернуть Найти похожие ветки
← →
McSimm2 (2003-07-03 16:30) [0]Есть запрос:
select *
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
Возвращает соответствующую выборку. Как мне теперь посмотреть записи из таблицы table1, которые не попали в эту выборку, т.е. не удовлетворяющие сразу всем условиям в where ?
← →
sniknik (2003-07-03 16:37) [1]....
where NOT (s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3)
← →
Johnmen (2003-07-03 16:39) [2]select *
from table1 n, table2 s
where s.field1(+) = n.field1
AND s.field2(+) = n.field2
AND s.field3(+) = n.field3
AND ((n.field1 IS NULL) OR (n.field2 IS NULL) OR (n.field3 IS NULL))
← →
McSimm2 (2003-07-03 16:39) [3]таким образом записи пермножаются и их возвращается больше чем надо ....
← →
McSimm2 (2003-07-03 16:40) [4]Johnmen © (03.07.03 16:39)
Сейчас попробую (в какой раз спасаеш меня :)))
← →
roottim (2003-07-03 16:46) [5]1.
SELECT T.*
FROM TABLE1 T
MINUS
select N.*
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
2.
SELECT T.*
FROM TABLE1 T
WHERE NOT EXISTS(
select N.*
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
AND T.КЛЮЧ = N.КЛЮЧ
)
← →
McSimm2 (2003-07-03 16:54) [6]roottim (03.07.03 16:46)
1.
на
select N.*
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
вернул 1500 записей, на
SELECT T.*
FROM TABLE1 T
MINUS
select N.*
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
порядка 100000 :((
← →
roottim (2003-07-03 17:03) [7]ну тут объяснение одно...
2-й селект дает перемножение в n раз...
2-й вариант должен отработать точно!...
еще 3-й ... если тебе подходит...
select N.*
from table1 n
where not exists (
select * from table 2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
)
← →
McSimm2 (2003-07-03 17:06) [8]Да ты прав - одной записи первой таблице может "соответствовать "несколько из второй
Второй вариант зараза вообще 0 записей вернул. (сделал как у тебя в примере но без условия которое ты выделил жирным по причине того, что такого поля в таблице не имеется :(
← →
McSimm2 (2003-07-03 17:07) [9]А-а-а-а, млин торможу - количество полей разное во внешнем - и в подзапросе экзиста ....
← →
McSimm2 (2003-07-03 17:11) [10]Не и так то же не работает :(
Если написать
select t.*
from ivc.nutsami t
where exists
(SELECT distinct n.*
FROM ivc.nutsami n,
(SELECT ksm_n_lc, ksm_jeu, ksm_rajon,
vet_famil
|| " "
|| vet_imj
|| " "
|| vet_otch AS ffio
FROM ivcdba.ssobes_new) s
WHERE s.ksm_n_lc = n.n_lc
AND s.ksm_jeu = n.jeu
AND s.ksm_rajon = n.raion
AND s.ffio = n.fio
)
возвращает 100000 записей а если not exists то 0 ...
← →
McSimm2 (2003-07-03 17:15) [11]А вот если
SELECT distinct n.*
FROM ivc.nutsami n,
(SELECT ksm_n_lc, ksm_jeu, ksm_rajon,
vet_famil
|| " "
|| vet_imj
|| " "
|| vet_otch AS ffio
FROM ivcdba.ssobes_new) s
WHERE s.ksm_n_lc = n.n_lc
AND s.ksm_jeu = n.jeu
AND s.ksm_rajon = n.raion
AND s.ffio = n.fio
то 1500 записей, когда как в nutsami 100000 записей, а в ssobes_new 2500
← →
ЮЮ (2003-07-04 03:07) [12]>Как мне теперь посмотреть записи из таблицы table1, которые не попали в эту выборку, т.е. не удовлетворяющие сразу всем условиям в where ?
Сформулируруй точнее и ответ придёт сам: "Как найти записи в Table1, для которых в Table2 нет ни одной записи, у которой значения всех полей field1, fiel2, field3 совпадают".
Решение:
SELECT table1.*
FROM
(
SELECT DISTINT n.<ключевое поле>
FROM
table1 n
LEFT JOIN table2 s
ON (s.field1 = n.field1) AND (s.field2 = n.field2) AND (s.field3 = n.field3)
WHERE (s.<ключевое поле> IS NULL) /* т.е. нет соответствующей записи в table2 */
) KeysOnly
LEFT JOIN table1 on KeysOnly.<ключевое поле> = Table1.<ключевое поле>
← →
ЮЮ (2003-07-04 03:11) [13]Sorry, это на "всемогущем" MS SQL.
Подзапрос KeysOnly можно воткнуть в EXISTS
← →
kaif (2003-07-04 04:37) [14]select ...
from ...
where exists и так далее
всегда вернет ровно столько записей, сколько в в первой таблице или вообще не вернет ни одной.
Так как в условии КАЖДАЯ строка проверяется на истинность условия, которое всего лишь проверяет, есть ли хоть одна запись во втором selecte.
Правильное решение:
select * from table1
where not id in
( select n.id
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
)
Для него желательно иметь простой первичный ключ id типа integer в первой таблице. Если такого ключа нет, то ситуация намного хуже, но тоже поправима:
select * from table1
where not field1+field2+field3 in
( select n.field1+n.field2+n.field3
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
)
Знак + я поставил условно. Имеется в виду некоторое вычисление, которое из 3 полей соберет нечто. Так как типы полей мне неизвестны, то трудно сказать, что это будет такое. Для строк это конкатенация с форматированием, которое даст непересекающиеся значения, например:
"aaa", "b", "bbb" нужно изобразить как
"aaa b bbb "
(с учетом длины полей добить пробелами и склеить строки в одну)
Приведенное решение работает для InterBase. Для ORACLE тоже должно работать.
← →
kaif (2003-07-04 04:42) [15]Есть еще так называемое Тетта-объединение.
Но я не помню, как оно делается. Можно поискать, но этой книги под рукой сейчас нет.
← →
kaif (2003-07-04 04:48) [16]Да, кстати, запрос:
select * from table1
where not field1+field2+field3 in
(select field1+field2+field3
from table2)
выглядит с виду еще короче и по логике проще, но это не значит, что он будет работать быстрее. Хотя это зависит от сервера.
На IB, например, я бы написал ХП для второго select-а и тогда
2-х каскадный запрос сработал бы мгновенно. ХП сделала бы выборку только 1 раз и дальше поиск шел бы в уже суженном наборе. Тогда я бы точно применил самое первое решение, что я привел (самый маленький второй набор).
Возможно, ORACLE может оптимизировать вложенный SELECT так, чтобы он выполнился один раз и тогда самое первое приведенное решение - самое быстрое. Второе стоит попробовать для сравнения скорости и понимания того, как работает сервер.
← →
Val (2003-07-04 11:54) [17]select * from table1 where not exists
( select 1 from
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3)
← →
petr_v_a (2003-07-04 12:57) [18]SELECT T.*
FROM TABLE1 T
WHERE T.КЛЮЧ NOT IN
(
select T.КЛЮЧ
from table1 n, table2 s
where s.field1 = n.field1
AND s.field2 = n.field2
AND s.field3 = n.field3
)
Самый большой простор для работы оптимайзера, если с ним все хорошо, будет быстрый результат на любых данных
> roottim (03.07.03 16:46) Вариант 2
Не есть хорошо, MINUS - дополнительная сортировка
← →
kaif (2003-07-05 13:33) [19]2 Val © (04.07.03 11:54)
Твое решение неправильное.
Условие exists просто проверяет, есть ли хоть одна строка во втором select. Поэтому твой запрос вернет либо все строки первой таблицы, либо ни одной.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2003.07.28;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.006 c