powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Не получается правильно составить запрос с not in
5 сообщений из 5, страница 1 из 1
Не получается правильно составить запрос с not in
    #39317518
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть такой запрос:
Код: plsql
1.
2.
3.
4.
5.
select *
from ACCIDENT A
where A.IS_DELETED = 0
and A.ACCIDENT_DATE is not null
and A.ACCIDENT_DATE < trunc(sysdate, 'MM')


В возвращаемом наборе есть поле accident_id (A.ACCIDENT_ID), среди значений есть, например: 100, 200, 300.

Есть такой запрос:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
  select * --BL.ACCIDENT_ID
  from BONUS_LIST BL
  join BONUS_TYPE BT on (BT.BONUS_TYPE_ID = BL.BONUS_TYPE_ID)
  join BONUS_STATE BS on (BS.BONUS_STATE_ID = BL.BONUS_STATE_ID)
  where BL.IS_DELETED = 0
  and BT.CODE = 'refund'
  and BS.IS_DONE = 1


В возвращаемом наборе также есть поле accident_id (BL.ACCIDENT_ID), среди значений есть, например: 100, 200.

Выполняю такой запрос:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select *
from ACCIDENT A
where A.IS_DELETED = 0
and A.ACCIDENT_DATE is not null
and A.ACCIDENT_DATE < trunc(sysdate, 'MM')
and A.ACCIDENT_ID not in
(
  select BL.ACCIDENT_ID
  from BONUS_LIST BL
  join BONUS_TYPE BT on (BT.BONUS_TYPE_ID = BL.BONUS_TYPE_ID)
  join BONUS_STATE BS on (BS.BONUS_STATE_ID = BL.BONUS_STATE_ID)
  where BL.IS_DELETED = 0
  and BT.CODE = 'refund'
  and BS.IS_DONE = 1
)


Я считал, что должна получится строка с accident_id=300.
Однако возвращается пустой набор.

Если второй запрос перенести в left join, а в where добавить для него проверку accident_id is null, то результаты получаются ожидаемые.
Но мне кажется, что первый вариант более правильный.

План первого запроса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
SELECT STATEMENT  ALL_ROWSCost: 17  Bytes: 190  Cardinality: 5  					
	9 FILTER  				
		1 TABLE ACCESS FULL TABLE ACCIDENT Cost: 5  Bytes: 190  Cardinality: 5  			
		8 NESTED LOOPS  Cost: 5  Bytes: 37  Cardinality: 1  			
			5 NESTED LOOPS  Cost: 4  Bytes: 21  Cardinality: 1  		
				3 TABLE ACCESS BY INDEX ROWID TABLE BONUS_TYPE Cost: 1  Bytes: 10  Cardinality: 1  	
					2 INDEX UNIQUE SCAN INDEX (UNIQUE) BONUS_TYPE_CODE Cost: 0  Cardinality: 1  
				4 TABLE ACCESS FULL TABLE BONUS_LIST Cost: 3  Bytes: 11  Cardinality: 1  	
			7 TABLE ACCESS BY INDEX ROWID TABLE BONUS_STATE Cost: 1  Bytes: 16  Cardinality: 1  		
				6 INDEX UNIQUE SCAN INDEX (UNIQUE) BONUS_STATE_PK Cost: 0  Cardinality: 1  	

План второго запроса:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
SELECT STATEMENT  ALL_ROWSCost: 13  Bytes: 102  Cardinality: 2  							
	10 FILTER  						
		9 HASH JOIN OUTER  Cost: 13  Bytes: 102  Cardinality: 2  					
			1 TABLE ACCESS FULL TABLE ACCIDENT Cost: 5  Bytes: 190  Cardinality: 5  				
			8 VIEW BILLING. Cost: 8  Bytes: 13  Cardinality: 1  				
				7 HASH JOIN  Cost: 8  Bytes: 37  Cardinality: 1  			
					5 NESTED LOOPS  Cost: 4  Bytes: 672  Cardinality: 32  		
						3 TABLE ACCESS BY INDEX ROWID TABLE BONUS_TYPE Cost: 1  Bytes: 10  Cardinality: 1  	
							2 INDEX UNIQUE SCAN INDEX (UNIQUE) BONUS_TYPE_CODE Cost: 0  Cardinality: 1  
						4 TABLE ACCESS FULL TABLE BONUS_LIST Cost: 3  Bytes: 352  Cardinality: 32  	
					6 TABLE ACCESS FULL TABLE BONUS_STATE Cost: 3  Bytes: 16  Cardinality: 1  		
________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
Не получается правильно составить запрос с not in
    #39317523
Фотография AlexFF__|
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.,

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
select *
from ACCIDENT A
where A.IS_DELETED = 0
and A.ACCIDENT_DATE is not null
and A.ACCIDENT_DATE < trunc(sysdate, 'MM')
and A.ACCIDENT_ID not in
(
  select BL.ACCIDENT_ID
  from BONUS_LIST BL
  join BONUS_TYPE BT on (BT.BONUS_TYPE_ID = BL.BONUS_TYPE_ID)
  join BONUS_STATE BS on (BS.BONUS_STATE_ID = BL.BONUS_STATE_ID)
  where BL.IS_DELETED = 0
  and BT.CODE = 'refund'
  and BS.IS_DONE = 1
  and BL.ACCIDENT_ID is not null <----------------------------------------------------------------
)
...
Рейтинг: 0 / 0
Не получается правильно составить запрос с not in
    #39317543
Фотография Elic
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
RTFM IN Condition (FAQ) : "If any item in the list following a NOT IN operation evaluates to null, then …"
...
Рейтинг: 0 / 0
Не получается правильно составить запрос с not in
    #39317637
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek B.Есть такой запрос:
Код: plsql
1.
2.
3.
4.
5.
select *
from ACCIDENT A
where A.IS_DELETED = 0
and A.ACCIDENT_DATE is not null
and A.ACCIDENT_DATE < trunc(sysdate, 'MM')





сразу:
это условие лишнее

and A.ACCIDENT_DATE is not null
...
Рейтинг: 0 / 0
Не получается правильно составить запрос с not in
    #39317664
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, проглядел.
AlexFF__|, Elic, спасибо.

MasterZivand A.ACCIDENT_DATE is not null
Да, избыточно, но так запрос выполняется чуть быстрее.
В таблице ACCIDENT записей с пустыми ACCIDENT_DATE намного больше, чем с заполненными.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / Oracle [игнор отключен] [закрыт для гостей] / Не получается правильно составить запрос с not in
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]