Подтвердить что ты не робот

Oracle - создать временный набор результатов для использования в запросе

Как создать временный результирующий набор для использования в SQL без создания таблицы и вставки данных?

Пример: у меня есть список, например, 10 кодов. Я хочу поместить это в запрос, а затем запросить базу данных, чтобы узнать, какие коды в этом временном списке не существуют в таблице.

Если он уже был в таблице, я мог бы сделать что-то вроде:

SELECT
  ITEM_CODE
FROM
  TEMP_ITEMS
MINUS
SELECT
   ITEM_CODE
FROM
   M_ITEMS

Является ли это способом без использования PL/SQL и чистого SQL для создания временного набора строк перед запросом? Пожалуйста, не отвечайте с чем-то вроде:

SELECT 1 FROM DUAL
UNION ALL
SELECT 2 FROM DUAL

Я как бы думаю о чем-то, где я могу предоставить свои коды в инструкции IN, и превращает это в строки для использования в более позднем запросе.

Изменить: так что все знают мою цель здесь, в основном я иногда получаю список кодов продуктов, которые мне нужны, чтобы найти, какие из них в списке не настроены в нашей системе. Я хочу, чтобы быстрый способ бросить это в SQL-запрос, чтобы я мог видеть, какие из них не находятся в системе (вместо импорта данных и т.д.). Я обычно помещаю их в excel, затем делаю формулу, например:

="'"&A1&"',"

Итак, я могу создать список, разделенный запятыми.

4b9b3361

Ответ 1

Если вы используете oracle 11g, вы можете сделать это

with t as 
(
 select (column_value).getnumberval() Codes from xmltable('1,2,3,4,5')
)
SELECT * FROM t
WHERE NOT EXISTS (SELECT 1 FROM M_ITEMS M WHERE codes = M.ITEM_CODE);

или

with t as 
(
 select (column_value).getstringval() Codes from xmltable('"A","B","C"')
)
SELECT * FROM t
WHERE NOT EXISTS (SELECT 1 FROM M_ITEMS M WHERE codes = M.ITEM_CODE);

Ответ 2

Я бы пошел с:

with t as (
    select 1 as val from dual union all
    select 2 as val from dual
)
select . . .

И затем используйте "t" или как вы его называете, в последующем блоке запроса.

Я не уверен, что возражает против использования метода select., просто введите нужные значения в столбце Excel и создайте код для каждого значения, скопировав формулу. Затем вставьте результаты обратно в свой интерфейс запроса.

Если вы хотите использовать временную таблицу, вы можете использовать предложение values. В качестве альтернативы вы можете использовать строковые функции, если хотите только функциональность IN. Поместите значения в список, разделенный запятыми, и проверьте, соответствует ли оно определенному значению:

where ','||<list>||',' like '%,'||col||',%'

Ответ 3

Есть два подхода, к которым я бы наклонился:

1. Глобальная временная таблица

Хотя вы говорите, что не хотите создавать таблицу, это зависит от того, почему вы не хотите использовать таблицу. Если вы решите создать глобальную временную таблицу, строки будут видны только для сеанса, который их вставил, чтобы он имел приватную таблицу в памяти, но предоставлял вам все преимущества реальной таблицы, т.е. Имел возможность запрашивать и присоединяться к нему.

2. Конвейерная функция

Вы можете создать функцию, которая возвращает результаты в форме, которая может быть запрошена с помощью оператора TABLE(). Подробнее здесь: http://www.oracle-base.com/articles/misc/pipelined-table-functions.php

Ответ 4

Это немного странно. Но вы можете анализировать строку в отдельные строки, используя регулярные выражения, предполагая, что вы используете 10g или более поздние версии. Например

SQL> ed
Wrote file afiedt.buf

  1   SELECT REGEXP_SUBSTR('a,b,c,def,g', '[^ |,]+', 1, LEVEL) parsed_str
  2     FROM dual
  3* CONNECT BY LEVEL <= REGEXP_COUNT('a,b,c,def,g', '[^ |,]+')
SQL> /

PARSED_STR
--------------------------------------------
a
b
c
def
g

Лично я бы нашел конвейерную функцию таблицы или блок PL/SQL, который генерирует коллекцию, которую легче понять, но если вам нужно это сделать в SQL, вы можете.

Основываясь на вашем редактировании, если вы получаете список кодов продуктов, которые уже находятся в каком-то файле, кажется, имеет смысл использовать внешнюю таблицу для отображения файла в виде таблицы или для использования SQL * Loader для загрузки данных в таблицу (временную или постоянную), которую вы можете запросить. Запрет любого из этих параметров, если вы действительно хотите управлять списком в Excel сначала, имеет смысл генерировать список IN в Excel и просто копировать и передавать его в ваш запрос. Создание списка разделенных запятыми кодов в Excel только для синтаксического разбора этого списка в него. Элементы-элементы в SQL выглядят как слишком много шагов.

Ответ 5

Это интересно, потому что это не объединение и не вписывается в один выбор. Вы должны ввести строку с разделителями ('a/b/c/def') два раза, хотя:

SELECT regexp_substr('a/b/c/def', '[^/]+', 1, ROWNUM) var,
regexp_substr('2/432/sd/fsd', '[^/]+', 1, ROWNUM) var2
FROM dual
CONNECT BY LEVEL <= length(regexp_replace('a/b/c/def', '[^/]', '')) + 1;

var var2
=== ====
a   2
b   432
c   sd
def fsd

Примечание. Кредиты переходят к: fooobar.com/info/440050/...

Итак, используя предложение with, он даст следующее:

with tempo as (
SELECT regexp_substr('a/b/c/def', '[^/]+', 1, ROWNUM) var,
regexp_substr('2/432/sd/fsd', '[^/]+', 1, ROWNUM) var2
FROM dual
CONNECT BY LEVEL <= length(regexp_replace('a/b/c/def', '[^/]', '')) + 1
)
select ...

или вы можете использовать его в предложении from:

select ...
from (
SELECT regexp_substr('a/b/c/def', '[^/]+', 1, ROWNUM) var,
regexp_substr('2/432/sd/fsd', '[^/]+', 1, ROWNUM) var2
FROM dual
CONNECT BY LEVEL <= length(regexp_replace('a/b/c/def', '[^/]', '')) + 1
) tempo