【问题标题】:how to select a list of 10,000 unique ids from dual in oracle SQL如何在 oracle SQL 中从双重中选择 10,000 个唯一 ID 的列表
【发布时间】:2017-04-30 12:00:33
【问题描述】:

所以我无法创建或编辑表格(我是具有只读权限的用户),我想查找 10,000 个唯一 ID。我不能将它们放在 IN() 语句中,因为 oracle 限制超过 1000 个项目。

是否可以从 oracle 的 DUAL 表中选择整个列表?类似的东西:

select  
'id123,id8923,id32983,id032098,id308230,id32983289'  
from DUAL

【问题讨论】:

  • 它没有说这些是连续的数字。事实上,样本显示完全随机数
  • 你也可以试试IN (SELECT C1 FROM (SELECT 'id123' C1 FROM DUAL UNION ALL SELECT 'id8923' FROM DUAL UNION ALL SELECT 'id32983' FROM DUAL))
  • 你从哪里得到这 10000 个 ID?这不是另一个查询的结果吗?它是否可能是所有 id 的列表,除了少数几个?

标签: sql oracle dual-table


【解决方案1】:

使用collection(它们不限于像IN 子句那样的1000 个项目):

SELECT COLUMN_VALUE AS id
FROM   TABLE(
         SYS.ODCIVARCHAR2LIST(
           'id123', 'id8923', 'id32983', 'id032098', 'id308230', 'id32983289'
         )
       )

SYS.ODCIVARCHAR2LISTSYS.ODCINUMBERLIST 是在 SYS 架构中提供的集合类型。

您可以直接将其加入到 SELECTing 所在的任何表中,而无需使用 DUAL 表:

SELECT y.*
FROM   your_table y
       INNER JOIN TABLE(
         SYS.ODCIVARCHAR2LIST(
           'id123', 'id8923', 'id32983', 'id032098', 'id308230', 'id32983289'
         )
       ) i
       ON (y.id = i.COLUMN_VALUE);

如果您可以创建一个集合类型,那么您甚至不需要TABLE 表达式,并且可以使用MEMBER OF 运算符直接在WHERE 子句中使用它:

CREATE OR REPLACE TYPE stringlist IS TABLE OF VARCHAR2(200);
/
SELECT *
FROM   yourtable
WHERE  id MEMBER OF stringlist(
                      'id123', 'id8923', 'id32983', 'id032098', 'id308230', 'id32983289'
                    );

您甚至可以将值作为绑定参数传递 - 请参阅 my answer here

【讨论】:

    【解决方案2】:

    Oracle 仍然不支持VALUES 行构造函数,所以只有两个丑陋的解决方法:

    1000 项限制不适用于多列 IN 条件

    Expression Lists

    以逗号分隔的表达式列表最多可以包含 1000 个 表达式。逗号分隔的表达式集列表可以包含 任意数量的集合,但每个集合不能超过 1000 表达式。

    所以你可以这样做:

    where (1,id) in ( (1,'id123'),
                      (1,'id8923'),
                      (1,'id32983'), 
                      (1,'id032098'), .... )
    

    或者使用一个又大又丑的UNION ALL:

    with idlist (xid) as (
      select 'id123' from dual union all 
      select 'id8923' from dual union all 
      .....
      select 'id32983' from dual 
    )
    select ...
    from some_table
    where id in (select xid from idlist);
    

    【讨论】:

    • 哇。您是如何解决多列问题的?任何文档/官方参考/半官方参考?
    • @DuduMarkovitz:不,我没有参考。
    • 您能回忆起您第一次看到它的地点/时间吗?
    • @DuduMarkovitz:我在这里看到了这个
    • 快速搜索并添加对您答案的引用。我希望一切都好。由你。
    【解决方案3】:

    另一种解决方法

    select  *
    
    from    t
    
    where   id in ('id1','id2','id3',...,'id1000')
         or id in ('id1001','id1002','id1003',...,'id2000')
         or id in ('id2001','id2002','id2003',...,'id3000')
         or ...
    

    【讨论】:

      【解决方案4】:

      一种解决方案是 WITH 子句:

      with ids as (
         select 'id123' as uid from dual union all
         select 'id8923' as uid from dual union all
         select 'id32983' as uid from dual union all
         select 'id032098' as uid from dual union all
         select 'id308230' as uid from dual union all
         select 'id32983289' as uid from dual 
      )
      select *
      from ids
           join your_table yt
           on yt.id = ids.uid  
      

      这可能看起来有点麻烦,但大概您在电子表格或其他任何东西中都有您的 UID 列表。如果是这样,那么使用正则表达式生成这些选择语句就很容易了。只需将列剪切'n'粘贴到支持正则表达式搜索和替换的编辑器中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-02-14
        • 1970-01-01
        • 2018-09-11
        • 1970-01-01
        • 2020-11-27
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多