Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
4-91961
Grayver
2003-05-22 21:50
2003.07.28
2 вопроса (про трей и едит)


14-91913
Knight
2003-07-12 10:42
2003.07.28
Фестивать Козьмы Пруткова


1-91720
Endi
2003-07-14 17:44
2003.07.28
Прозрачный TEdit


14-91844
Виталик
2003-07-10 20:34
2003.07.28
Компоненты для компрессии RAR, ZIP


3-91659
khvalera
2003-07-06 21:41
2003.07.28
Поиск





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский