Oracle SQL -子查询与仅按获取前1行排序

35g0bw71  于 2023-03-22  发布在  Oracle
关注(0)|答案(3)|浏览(246)

| 识别号|参考编号|姓名|薪金|
| - ------|- ------|- ------|- ------|
| 1个|Dummy1|史密斯|小行星5487|
| 第二章|Dummy2|蒂姆|小行星3123|
| 三个|Dummy1|史密斯|四三二四|
| 四个|Dummy4|史蒂夫|九九五七七|
| 五个|Dummy5|马特|五五五一四四四|
| 六个|Dummy2|蒂姆|432112|
| 七|Dummy7|布拉德|八九八九七|
| 八个|Dummy3|凯文|123213|
| 九|Dummy3|凯文|小行星7878|
| 十个|Dummy3|凯文|四三五五五|
| 十一|Dummy2|蒂姆|四三二|
| 十二|Dummy8|杰瑞|三二一二三|
| 十三|Dummy8|杰瑞|四三四三四|
| 十四|Dummy9|盖勒|8989897|
| 十五|Dummy2|蒂姆|1234|
| 十六|Dummy6|杰夫|8989987|
| 十七|Dummy1|史密斯|545453|
| 十八|Dummy2|蒂姆|小行星6464|
| 十九|Dummy2|蒂姆|四三五三五|
| 二十个|Dummy1|史密斯|64643|
| 二十一|Dummy8|杰瑞|九九五|
我的表中有上述数据,哪个查询更有效,更快地获取数据.我所需的数据是得到Dummy2Salary,其中Id是最大值,即Dummy 2的最新工资.
注:这是一个数据超过500万的审计表。
查询1:

select a.Name,
       a.Salary
from   table a
where  a.REF_NO = 'Dummy2'
and    a.ID = (select max(id) from table where REF_NO = a.REF_NO)

查询2:

select Name,
       Salary
from   table
where  REF_NO = 'Dummy2'
order by ID desc
fetch first row only
0s0u357o

0s0u357o1#

它们是不同的查询,并且假设您可以有重复的id,将产生不同的结果,因此您不能轻松地比较它们。

SELECT Name,
       Salary
FROM   table_name
WHERE  ref_no = 'Dummy2'
ORDER BY id DESC
FETCH FIRST ROW ONLY

即使存在重复的id,也最多返回一行。
您可以实现查询:

SELECT Name,
       Salary
FROM   table_name
WHERE  ref_no = 'Dummy2'
AND    id = (SELECT max(id) FROM table_name WHERE ref_no = a.ref_no)

作为:

SELECT Name,
       Salary
FROM   table_name
WHERE  ref_no = 'Dummy2'
ORDER BY id DESC
FETCH FIRST ROW WITH TIES;

并将返回给定ref_no的重复最新id的行数。

u59ebvdq

u59ebvdq2#

查询1和查询2给出的结果相同,但查询2的效率比查询1高,原因是查询1的开销更大,因为查询1中包含子查询。

piztneat

piztneat3#

[按照MT 0的建议编辑-具有唯一ID值的全新表]

(Code我以前发布的仍然可以在 * 编辑 * 链接后面访问)

SQL> CREATE TABLE test
  2  (
  3     id            NUMBER GENERATED ALWAYS AS IDENTITY,
  4     object_name   VARCHAR2 (200)
  5  );

Table created.

SQL> CREATE INDEX ui1_test
  2     ON test (id);

Index created.

SQL> BEGIN
  2     FOR i IN 1 .. 100
  3     LOOP
  4        INSERT INTO test (object_name)
  5           SELECT object_name FROM all_objects;
  6     END LOOP;
  7  END;
  8  /

PL/SQL procedure successfully completed.

SQL> SELECT COUNT (*) FROM test;

  COUNT(*)
----------
   5814300

(OK,580万与我之前使用的33亿相去甚远,但也几乎是OP提到的三倍(200万)
表格内容:

SQL> SELECT *
  2    FROM test
  3   WHERE ROWNUM <= 5;

        ID OBJECT_NAME
---------- ------------------------------
         1 ORA$BASE
         2 DUAL
         3 DUAL
         4 MAP_OBJECT
         5 SYSTEM_PRIVILEGE_MAP

现在我们来比较一下:

SQL> SET TIMING ON
SQL> SELECT id
  2    FROM test
  3   WHERE id = (SELECT MAX (id) FROM test);

        ID
----------
   5814300

Elapsed: 00:00:00.01
SQL>   SELECT id
  2      FROM test
  3  ORDER BY id DESC
  4     FETCH FIRST ROW ONLY;

        ID
----------
   5814300

Elapsed: 00:00:00.01
SQL>

没有区别(我运行了几次)。
正如我之前评论的那样,你不能指望在小数据集上有任何差异,200万(或600万)并不多。

相关问题