【问题标题】:Oracle Fetch Next Row Limit by unique id'sOracle 通过唯一 id 获取下一行限制
【发布时间】:2022-01-04 08:36:40
【问题描述】:

我有一个表格,数据如下所示,

+-------+----------------+----------------+
|  Id   |    HierUnitId  |  ObjectNumber  |
+-------+----------------+----------------+
|  10   |     3599       |     1          |
|  10   |     3599       |     2          |
|  20   |     3599       |     3          |
|  20   |     3599       |     4          |
|  20   |     3599       |     1          |
|  30   |     3599       |     2          |
|  30   |     3599       |     3          |
+-------+----------------+----------------+

我有一个选择查询

SELECT ID FROM TEST
FETCH NEXT :LIMIT ROWS ONLY

现在我想使用limit的值来限制行数。 当 Limit 的值为 2 时,我想要两个不同的 id,即最多 5 行。但是,从查询中我只会得到两行 10 作为 id。有人可以帮助我使用不同的 id 限制行吗? 我想要的是输出中不同 id 的总数是有限的。

【问题讨论】:

  • 样本数据很好,但您还需要指定预期结果。
  • 请注意,没有 ORDER BY 的 FETCH NEXT 可能会返回或多或少的随机行。

标签: sql oracle distinct


【解决方案1】:

使用DENSE_RANK 分析函数根据唯一/不同的ID 值对行进行编号,然后对其进行过滤:

SELECT id
FROM   (
  SELECT ID,
         DENSE_RANK() OVER (ORDER BY id) AS rnk
  FROM   test
)
WHERE  rnk <= 2;

其中,对于样本数据:

CREATE TABLE test (Id, HierUnitId, ObjectNumber ) AS
SELECT 10, 3599, 1 FROM DUAL UNION ALL
SELECT 10, 3599, 2 FROM DUAL UNION ALL
SELECT 20, 3599, 3 FROM DUAL UNION ALL
SELECT 20, 3599, 4 FROM DUAL UNION ALL
SELECT 20, 3599, 1 FROM DUAL UNION ALL
SELECT 30, 3599, 2 FROM DUAL UNION ALL
SELECT 30, 3599, 3 FROM DUAL;

输出:

ID
10
10
20
20
20

db小提琴here

【讨论】:

    【解决方案2】:

    正如您在评论中所说,您需要能够定义应该显示多少个不同的 id。对于这种情况,我建议您先找到这些 id(请参阅 distinct_ids 部分),然后获取您需要的所有行

    with distinct_ids as (
      select distinct id
        from test_data  
       order by id
       fetch first :limit rows only)  
    
    select id
      from test_data td
      join distinct_ids di
        on td.id = di.id
    

    【讨论】:

    • 这不起作用,因为限制将决定不同 id 的数量。 Id 可以有任何值。我已经更新了我的问题,你可以看看它。
    • @PulkitSharma 请检查我的更新答案
    【解决方案3】:

    如果您需要 一些 个不同的 ID,没有任何特定的顺序,那么您可以将 fetch next ... 放入带有 distinct 关键字的子查询中。 ID 列上的索引将适合避免两次全表扫描(我假设 ID 不能为空)

    select /*+gather_plan_statistics*/
      *
    from t
    where id in (
      select distinct id
      from t
      where id is not null
      fetch next 2 rows only
    )
    
    身份证 |希伦尼特|对象编号 -: | ---------: | ------------: 1 | 3599 | 1 1 | 3599 | 2 2 | 3599 | 3 2 | 3599 | 4 2 | 3599 | 1
    select *
    from table(dbms_xplan.display_cursor(
      format => 'ALL -PROJECTION -ALIAS ALLSTATS LAST'
    ))
    
    |计划表输出 | | :------------------------------------------------ -------------------------------------------------- -------------------------------------------------- -------- | | SQL_ID 2sqqq53kpy5rj,子编号0 | | -------------------------------------- | | select /*+gather_plan_statistics*/ * from t where id in (select | |与 t 不同的 id,其中 id 不为空,仅获取下 2 行)| | | |计划哈希值:534568331 | | | | -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------- | | |身份证 |操作 |姓名 |开始 |电子行 |电子字节|成本 (%CPU)|电子时代 | A-行 |时间 |缓冲器 |欧米姆 | 1 内存 |使用过的内存 | | | -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------- | | | 0 |选择声明 | | 1 | | | 5 (100)| | 5 |00:00:00.01 | 3 | | | | | | | 1 |合并加入半 | | 1 | 5 | 115 | 5 (40)| 00:00:01 | 5 |00:00:00.01 | 3 | | | | | | | 2 |按索引 ROWID 访问表| T | 1 | 7 | 70 | 2 (0)| 00:00:01 | 6 |00:00:00.01 | 2 | | | | | | | 3 |索引全扫描 | T_IX | 1 | 7 | | 1 (0)| 00:00:01 | 6 |00:00:00.01 | 1 | | | | | | |* 4 |排序唯一 | | 6 | 2 | 26 | 3 (67)| 00:00:01 | 5 |00:00:00.01 | 1 | 2048 | 2048 | 2048 (0)| | | | 5 |查看 |大众_NSO_1 | 1 | 2 | 26 | 2 (50)| 00:00:01 | 2 |00:00:00.01 | 1 | | | | | | |* 6 |查看 | | 1 | 2 | 20 | 2 (50)| 00:00:01 | 2 |00:00:00.01 | 1 | | | | | | |* 7 | WINDOWS NOSORT STOPKEY | | 1 | 3 | 39 | 2 (50)| 00:00:01 | 2 |00:00:00.01 | 1 | 73728 | 73728 | | | | | 8 |查看 | | 1 | 3 | 39 | 2 (50)| 00:00:01 | 2 |00:00:00.01 | 1 | | | | | | | 9 |排序独特的 NOSORT | | 1 | 3 | 9 | 2 (50)| 00:00:01 | 2 |00:00:00.01 | 1 | | | | | | |* 10 |索引全扫描 | T_IX | 1 | 7 | 21 | 1 (0)| 00:00:01 | 6 |00:00:00.01 | 1 | | | | | | -------------------------------------------------- -------------------------------------------------- -------------------------------------------------- -------- | | | |谓词信息(由操作 id 标识):| | -------------------------------------------------- - | | | | 4 - 访问(“ID”=“ID”)| |过滤器("ID"="ID") | | 6 - 过滤器(“来自$_subquery$_004”。“rowlimit_$$_rownumber”

    db小提琴here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-10-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-13
      • 2023-03-25
      • 1970-01-01
      相关资源
      最近更新 更多