【问题标题】:Find total count from a sql query从 sql 查询中查找总数
【发布时间】:2018-02-27 09:04:27
【问题描述】:

我有一个where 条件为ROWNUM=10 的sql 查询。我将查询结果存储在一个GTT 表中。但有可能 sql 查询获取的记录多于提到的 WHERE 条件,即ROWNUM=10

所以我想知道,获取>10 记录的查询不是。

我可以通过执行两次相同的查询来实现这一点,即一次知道计数,第二次将记录插入gtt 表。

但是运行两次查询并不是一个好主意。

那么任何人都可以帮助我找到 sql 查询的计数而不执行两次。

【问题讨论】:

  • 共享查询...当你说rownum=10时,它肯定只返回10。如果不是,它的位置是错误的。
  • where rownum = 10 不会返回任何行,因为 rownum 的工作方式。 where rownum<=10 不会插入超过 10 行。 An MCVE 将帮助我们了解您实际在做什么以及您遇到的问题。您是否试图查看查询将找到多少行没有该条件,但仍只将前 10 行插入 GTT?
  • @AlexPoole,是的,我想知道在没有 ROWNUM 条件的情况下查询会找到多少行,但只在 gtt 中插入 10 行。请注意,我有动态 SQL 查询,并且在插入 GTTi 时使用 execute immediate insert into gtt select *from query were rownum<=10

标签: sql oracle


【解决方案1】:

如果您在 GTT 表中插入这些记录,并且您想知道您选择/插入了多少行,您可以使用 SQL%ROWCOUNT

Begin
    INSERT INTO GTT_TABLE
         SELECT *
           FROM QUERY_VIEW
          WHERE Condition() = '1';

    If SQL%ROWCOUNT > 10 Then
        dbms_output.put_line('Query returns ' || SQL%ROWCOUNT || ' rows.');
    End if;
End;

【讨论】:

  • 如果在选择本身中我给了 ROWNUMSQL%ROWCOUNT 不是也会返回 10 吗??
  • @teepu 是的,它将返回 10(或更少,如果您选择少于 10 行)。您不能使用该子句提取超过 10 行
【解决方案2】:

您可以使用在https://stackoverflow.com/a/17206119/7676742 找到的解决方案来获取记录和这些记录的计数。

SELECT COUNT(*) OVER (), c.*
FROM CUSTOMER c 
WHERE c.Name like 'foo%';

【讨论】:

  • 我有类似execute immediate insert into gtt select *from query were rownum<=10的查询。但我想知道如果没有这个 ROWNUM 条件,select 语句的计数是多少。
  • 你想同时得到不带where子句的查询计数和带where子句的查询结果,对吧?
【解决方案3】:

您可以在没有rownum 条件的情况下为查询打开一个游标并获取,直到您用完数据或达到第 11 行:

declare
  l_query varchar2(4000) := '<your query without rownum condition>';
  l_counter pls_integer := 0;
  l_cursor sys_refcursor;
  l_row gtt%rowtype;
begin
  open l_cursor for l_query;
  loop
    fetch l_cursor into l_row;
    exit when l_cursor%notfound;

    l_counter := l_counter + 1;
    if l_counter > 10 then
      dbms_output.put_line('Query got more than 10 rows');
      exit;
    end if;

    -- first 1-10 rows so insert
    insert into gtt values l_row;
  end loop;
end;
/

或者用一个集合来稍微提高效率:

declare
  l_query varchar2(4000) := '<your query without rownum condition>';
  l_cursor sys_refcursor;
  type t_tab is table of gtt%rowtype;
  l_tab t_tab;
begin
  open l_cursor for l_query;
  -- fetch gets at most 10 rows
  fetch l_cursor bulk collect into l_tab limit 10;
  -- up to 10 rows found are inserted
  forall i in 1..l_tab.count
    insert into gtt values l_tab(i);

  -- fetch again, if it finds anything then total row count > 10
  fetch l_cursor bulk collect into l_tab limit 1;
  if l_cursor%found then
    dbms_output.put_line('Query got more than 10 rows');
  end if;

  close l_cursor;
end;
/

但是,优化器通常可以使用rownum 条件来减少它必须做的工作(通过您可以在执行计划中看到的stopkey)。 可能运行两次查询仍然会更快、更有效,一次是插入的 10 行限制,另一次是 11 行的限制以获取计数,看看是否是不是 11。您应该测试这两种方法,看看哪种方法实际上更适合您的数据。 (当然还有其他建议!)

【讨论】:

    猜你喜欢
    • 2018-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-30
    • 2015-12-21
    • 1970-01-01
    • 2020-07-15
    • 2018-03-07
    相关资源
    最近更新 更多