[英]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.