Я хочу выбрать PART_NO из этой таблицы (INVENTORY_TRANSACTION_HIST_TAB), но не в том случае, если часть имеет TRANSACTION_CODE NREC или NISS. То есть PART_NO 101247 не должен возвращаться, а должен возвращаться 1001709.
Если я войду
SELECT
PART_NO
FROM INVENTORY_TRANSACTION_HIST_TAB WHERE TRANSACTION_CODE !='NISS' or TRANSACTION_CODE != 'NREC';
он по-прежнему возвращает номер детали 1012427, потому что явно имеет другие коды транзакций, отличные от NISS или NREC.
Это не возвращает строк.
Ах да, я неправильно понял вашу цель, извините.





Вы можете попробовать использовать не в коде с NISS и NREC
SELECT
PART_NO
FROM INVENTORY_TRANSACTION_HIST_TAB
WHERE PART_NO NOT IN (
SELECT
PART_NO
FROM INVENTORY_TRANSACTION_HIST_TAB
WHERE TRANSACTION_CODE IN ('NISS','NREC')
)
Это работает, спасибо scais (и другим за их предложения).
Здесь на помощь приходят аналитические функции:
SELECT part_no,
<other columns>
FROM (SELECT part_no,
<other columns>,
max(CASE WHEN transaction_code IN ('NISS', 'NREC') THEN 1 ELSE 0 end) OVER (PARTITION BY part_no) invalid_code_present
FROM inventory_transaction_hist_tab)
WHERE invalid_code_present = 0;
Подзапрос находит максимальное значение 1 для каждого part_no, если любая из строк для этого part_no имеет код транзакции NISS или NREC. Это значение возвращается для всех строк.
Затем внешний запрос фильтрует результаты, чтобы включить только строки part_no, в которых нет строк с исключенными кодами транзакций.
Н.Б. Я предположил, что вам нужно больше информации из строк, чем просто part_no. Если это не так, то сработает агрегированный запрос:
SELECT part_no
FROM inventory_transaction_hist_tab
GROUP BY part_no
HAVING MAX(CASE WHEN transaction_code IN ('NISS', 'NREC') THEN 1 ELSE 0 END) = 0;
Если вам Только нужен номер детали и только разные значения, поэтому вы видите только один результат для 1001709, а не 6, вы можете использовать условную агрегацию:
select part_no
from inventory_transaction_hist_tab
group by part_no
having max(case when transaction_code in ('NISS', 'NREC') then transaction_code end) is null;
Если вы хотите увидеть все строки для 1001709, альтернативой запросу @scaisEdge является использование not exists:
select part_no, transaction_code
from inventory_transaction_hist_tab t1
where not exists (
select *
from inventory_transaction_hist_tab t2
where t2.part_no = t1.part_no
and t2.transaction_code in ('NISS', 'NREC')
);
Вы можете попробовать оба и посмотреть, какой из них работает лучше. Или @Boneist, у которого есть то преимущество, что он попадает в стол только один раз, что, вероятно, компенсирует любые накладные расходы аналитической функции.
Попробуйте
ANDвместоOR.