繁体   English   中英

Oracle-创建一个临时结果集以供查询使用

[英]Oracle- create a temporary resultset for use in a query

如何在不创建表和插入数据的情况下创建用于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&"',"

这样我就可以创建逗号分隔列表了。

如果你使用的是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);

我会选择:

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||',%'

我倾向于两种方法:

1.全球临时表

虽然你说你不想创建一个表,这取决于你为什么不想要一个表。 如果您选择创建全局临时表,则行只对插入它们的会话可见,因此它就像拥有一个私有的内存表,但为您提供了真实表的所有好处 - 即能够查询和加入它。

2.流水线功能

您可以创建一个函数,该函数以可以使用TABLE()运算符查询的形式返回结果。 更多信息: http//www.oracle-base.com/articles/misc/pipelined-table-functions.php

这个很有趣,因为它不是一个联合并且适合单个选择。 你必须输入带分隔符的字符串('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

注意:积分转到: https//stackoverflow.com/a/1381495/463056

所以使用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

它有点看起来很好看。 但是,假设您使用的是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中操作列表,那么在Excel中生成IN列表并将其复制并传递到查询中会更有意义。 在Excel中生成以逗号分隔的代码列表,只是为了将该列表解析为SQL中的组成元素,这似乎是太多的步骤。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM