Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从SQL查询(Oracle)字段中的最小值获取所有行数据_Sql_Oracle_Group By_Subquery_Min - Fatal编程技术网

从SQL查询(Oracle)字段中的最小值获取所有行数据

从SQL查询(Oracle)字段中的最小值获取所有行数据,sql,oracle,group-by,subquery,min,Sql,Oracle,Group By,Subquery,Min,我无法通过指定字段的最小值从SQL查询中获取所有信息的行。以下是我正在使用的数据和我试图获取的数据的基本示例: SELECT 1 AS NUM_, 'ABC' AS LET_ FROM DUAL UNION SELECT 2 AS NUM_, 'DEF' AS LET_ FROM DUAL UNION SELECT 3 AS NUM_, 'GHI' AS LET_ FROM DUAL; 上述查询将产生以下结果: NUM_ | LET_ ----------- 1 | ABC 2 |

我无法通过指定字段的最小值从SQL查询中获取所有信息的行。以下是我正在使用的数据和我试图获取的数据的基本示例:

SELECT 1 AS NUM_, 'ABC' AS LET_ FROM DUAL
UNION
SELECT 2 AS NUM_, 'DEF' AS LET_ FROM DUAL
UNION
SELECT 3 AS NUM_, 'GHI' AS LET_ FROM DUAL;
上述查询将产生以下结果:

NUM_ | LET_
-----------
  1  | ABC
  2  | DEF
  3  | GHI
我只想要包含数据
1
ABC
的行。以下是我尝试过的:

SELECT MIN(LN.NUM_) AS MIN_NUM, 
       LN.LET_ 
FROM   (SELECT 1 AS NUM_, 'ABC' AS LET_ FROM DUAL
        UNION
        SELECT 2 AS NUM_, 'DEF' AS LET_ FROM DUAL
        UNION
        SELECT 3 AS NUM_, 'GHI' AS LET_ FROM DUAL) LN
GROUP BY LET_;

但是上面仍然给出了所有的行。我如何在
NUM\uu
列中的值最小的行上进行归零,给我
1
ABC

您的查询会为每个
LET\code>找到最小的
NUM\u
。要获得所有记录中的最小
NUM
,请使用
orderby
&
ROWNUM

试试这个

SELECT LN.NUM_ AS MIN_NUM, 
       LN.LET_ 
FROM   (SELECT 1 AS NUM_, 'ABC' AS LET_ FROM DUAL
        UNION
        SELECT 2 AS NUM_, 'DEF' AS LET_ FROM DUAL
        UNION
        SELECT 3 AS NUM_, 'GHI' AS LET_ FROM DUAL
        ORDER BY LN.NUM_) LN
Where ROWNUM = 1

在Oracle 12C中,您可以使用ANSI标准
仅获取第一行
语法:

SELECT 1 AS NUM_, 'ABC' AS LET_ FROM DUAL
UNION ALL
SELECT 2 AS NUM_, 'DEF' AS LET_ FROM DUAL
UNION ALL
SELECT 3 AS NUM_, 'GHI' AS LET_ FROM DUAL
ORDER BY 1
FETCH FIRST 1 ROW ONLY;

正如已经指出的那样,有不同的方法可以做到这一点:

一些方法:

  • 仅获取前1行
  • orderby
    在视图中,然后
    ROWNUM=1
  • (我的添加)
    MAX KEEP
  • (我的添加)不相关子查询
FETCH FIRST 1 ROW ONLY
是最简单的语法,并且执行得足够好。但是如果您有一个大表,那么其他方法也值得考虑

您的数据集太小,无法演示不同的性能结果,因此为了演示它们,让我们用
DBA\u对象创建一个表

create table matt_test as SELECT * FROM dba_objects;
create unique index matt_test_u1 on matt_test (object_id);
exec dbms_stats.gather_table_stats(USER, 'MATT_TEST');
然后,尝试一些不同的方法,并使用DBMS\u XPLAN测量每种方法:

马克斯保持 首先获取(注意内存使用情况) 不相关子查询 因此,您可以看到,如果可以利用索引,则不相关子查询的速度会快得多。
MAX KEEP
方法比
FETCH FIRST ROWS
方法性能稍好,因为它使用的内存更少

没有一种方法是最好的:每种方法都有自己的位置

如果我写这篇文章时不考虑性能(例如,较小的数据集),那么默认方法是
获取第一行

SELECT MAX (object_id) KEEP (DENSE_RANK FIRST ORDER BY object_id) object_id,
       MAX (object_name) KEEP (DENSE_RANK FIRST ORDER BY object_id) object_name
FROM   matt_test o;

------------------------------------------------------------------------------------------
| Id  | Operation          | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |           |      1 |        |      1 |00:00:00.29 |    8522 |
|   1 |  SORT AGGREGATE    |           |      1 |      1 |      1 |00:00:00.29 |    8522 |
|   2 |   TABLE ACCESS FULL| MATT_TEST |      1 |    555K|    555K|00:00:00.12 |    8522 |
------------------------------------------------------------------------------------------
SELECT object_id, object_name
FROM   matt_test o
order by object_id
fetch first 1 rows only;

---------------------------------------------------------------------------------------------------------------------------
| Id  | Operation                | Name      | Starts | E-Rows | A-Rows |   A-Time   | Buffers |  OMem |  1Mem | Used-Mem |
---------------------------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT         |           |      1 |        |      1 |00:00:00.33 |    8522 |       |       |          |
|*  1 |  VIEW                    |           |      1 |      1 |      1 |00:00:00.33 |    8522 |       |       |          |
|*  2 |   WINDOW SORT PUSHED RANK|           |      1 |    555K|      1 |00:00:00.33 |    8522 |  2048 |  2048 | 2048  (0)|
|   3 |    TABLE ACCESS FULL     | MATT_TEST |      1 |    555K|    555K|00:00:00.12 |    8522 |       |       |          |
---------------------------------------------------------------------------------------------------------------------------
select object_id, object_name
from matt_test
where object_id = ( SELECT min(object_id) FROM matt_test );

-------------------------------------------------------------------------------------------------------
| Id  | Operation                    | Name         | Starts | E-Rows | A-Rows |   A-Time   | Buffers |
-------------------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT             |              |      1 |        |      1 |00:00:00.01 |       7 |
|   1 |  TABLE ACCESS BY INDEX ROWID | MATT_TEST    |      1 |      1 |      1 |00:00:00.01 |       7 |
|*  2 |   INDEX UNIQUE SCAN          | MATT_TEST_U1 |      1 |      1 |      1 |00:00:00.01 |       6 |
|   3 |    SORT AGGREGATE            |              |      1 |      1 |      1 |00:00:00.01 |       3 |
|   4 |     INDEX FULL SCAN (MIN/MAX)| MATT_TEST_U1 |      1 |      1 |      1 |00:00:00.01 |       3 |
-------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("OBJECT_ID"=)