我为一家拥有DW-ETL设置的公司工作。我需要编写一个查询,该查询在WHEN - IN子句中查找超过2500个以上的值,也在WHERE - IN子句中查找超过1000个以上的值。基本上看起来像下面这样:

SELECT
    ,user_id
    ,CASE WHEN user_id IN ('user_n', +2500 user_[n+1] ) THEN 1
    ELSE 0
    ,item_id
FROM user_table
    WHERE item_id IN ('item_n', +1000 item_[n+1] );


您可能已经知道PL / SQL在IN子句中最多允许1000个值,所以我尝试添加OR - IN子句(如其他stackoverflow线程中所建议):

SELECT
    ,user_id
    ,CASE WHEN user_id IN ('user_n', +999 user_[n+1] )
     OR user_id IN ('user_n', +999 user_[n+1] )
     OR user_id IN ('user_n', +999 user_[n+1] ) THEN 1
     ELSE 0 END AS user_group
    ,item_id
FROM user_table
    WHERE item_id IN ('item_n', +999 item_[n+1] )
    OR item_id IN ('item_n', +999 item_[n+1] );


注意:我知道上面的示例中的数学是错误的,但是您明白了

问题是查询的最大执行时间为120分钟,并且作业被自动终止。因此,我用谷歌搜索了可以找到的解决方案,似乎临时表可能是我正在寻找的解决方案,但是老实说,我发现的所有示例都不十分清楚如何在表中包含所需的值以及如何在我的原始查询中使用此表。甚至ORACLE文档都没有太大帮助。

另一个潜在的问题是我的权限有限,而且我看到其他人提到在他们的公司中他们无权创建临时表。

我在研究中发现的一些信息:

ORACLE documentation

StackOverflow thread

[StackOverflow thread 2]

我发现的另一个解决方案是使用元组,如THIS thread中所述(我没有尝试过),因为正如另一个用户提到的那样,性能似乎受到很大影响。

任何有关如何使用临时表的指南,或者是否有人有另一种方法来处理此限制的指南,将不胜感激。

最佳答案

创建一个全局临时表,因此不创建任何撤消日志

CREATE GLOBAL TEMPORARY TABLE <table_name> (
<column_name>  <column_data_type>,
<column_name>  <column_data_type>,
<column_name>  <column_data_type>)
ON COMMIT DELETE ROWS;


然后根据用户列表到达的方式将数据导入到保留表中,然后运行

select 'INSERT INTO global_temporary_table <column> values '
|| holding_table.column
||';'
FROM holding_table.column;

This gives you insert statements as output which you run to insert the data.


然后

SELECT  <some_column>
FROM <some_table>
WHERE <some_value> IN
(SELECT <some_column> from <global_temporary_table>

10-04 19:29