如何创建临时结果集以便在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&"',"
这样我就可以创建逗号分隔列表了。
答案 0 :(得分:25)
如果您使用的是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);
答案 1 :(得分:4)
我会选择:
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||',%'
答案 2 :(得分:3)
我倾向于采用两种方法:
<强> 1。全球临时表
虽然您说您不想创建表格,但它取决于为什么您不想要表格。如果您选择创建全局临时表,则行只对插入它们的会话可见,因此它就像拥有一个私有的内存表,但为您提供了真实表的所有好处 - 即能够查询和加入它。
<强> 2。流水线功能
您可以创建一个函数,该函数以可以使用TABLE()
运算符查询的形式返回结果。更多信息:http://www.oracle-base.com/articles/misc/pipelined-table-functions.php
答案 3 :(得分:3)
这个很有意思,因为它不是一个联合并且适合单个选择。你必须输入带分隔符的字符串('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
答案 4 :(得分:2)
看起来有点好看。但是,假设您使用的是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 *似乎更有意义将数据加载到可以查询的表(临时或永久)中的加载器。除了这些选项之外,如果您真的想首先在Excel中操作列表,那么在Excel中生成IN
列表并将其复制并传递到查询中会更有意义。在Excel中生成以逗号分隔的代码列表,只是为了将该列表解析为SQL中的组成元素,这似乎是太多的步骤。