Я хочу выбрать PART_NO из этой таблицы (INVENTORY_TRANSACTION_HIST_TAB), но нет, если деталь имеет TRANSACTION_CODE NREC или NISS. Т.е. PART_NO 101247 не должен возвращаться, а 1001709 должен быть возвращен.

1012427

10001709

Если я войду

SELECT  
PART_NO
FROM INVENTORY_TRANSACTION_HIST_TAB WHERE TRANSACTION_CODE !='NISS' or TRANSACTION_CODE != 'NREC';

Он по-прежнему возвращает номер детали 1012427, потому что он, очевидно, имеет другие коды транзакций, которые не являются NISS или NREC.

-1
leesider 1 Май 2019 в 18:02

3 ответа

Лучший ответ

Вы можете попробовать использовать не в коде с 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')
  )
1
scaisEdge 1 Май 2019 в 15:15

Вот где аналитические функции приходят на помощь:

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;
2
Boneist 1 Май 2019 в 15:30

Если вам только нужен номер детали и только отдельные значения - поэтому вы видите только один результат для 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's, преимущество которого состоит в том, что вы попадаете в таблицу только один раз, что, вероятно, компенсирует любые издержки аналитической функции.

2
Boneist 1 Май 2019 в 15:37