sql - Oracle 12c 解析函数

标签 sql oracle oracle12c analytic-functions

有没有一种方法可以在给定数据集中,在同一条记录中,使用 Oracle 分析函数而不使用子查询来获取对应的值 X 对于最小值 Y?

例如:

如果我有以下数据集“ds1”:

Col1  Col2
A     1
B     2
C     3
D     4
E     4
A     10

通常,为了在 Col1 中找到对应于 Col2 中最小值“1”的值“A”,我会编写以下查询:

select ds1.col1
     from ds1
          , (select min (col2) col2
                  from ds1) min_ds1
     where ds1.col2 = min_ds1.col2
/

下面是这样一个测试用例的执行代码:

### 1014.010, Start time is: 10/30/2019 11:39:35am

MYUN@MYDB-C1>>create table ds1 (col1 varchar2 (1), col2 number)
  2  /

Table created.
Elapsed: 00:00:00.01

MYUN@MYDB-C1>>insert into ds1 (col1, col2)
  2       select 'A', 1 from dual
  3       union all select 'B', 2 from dual
  4       union all select 'C', 3 from dual
  5       union all select 'D', 4 from dual
  6       union all select 'E', 4 from dual
  7       union all select 'A', 10 from dual
  8  /

6 rows created.
Elapsed: 00:00:00.02

MYUN@MYDB-C1>>commit
  2  /

Commit complete.
Elapsed: 00:00:00.01

MYUN@MYDB-C1>>col col1 format a10
MYUN@MYDB-C1>>select ds1.col1
  2       from ds1
  3            , (select min (col2) col2
  4                    from ds1) min_ds1
  5       where ds1.col2 = min_ds1.col2
  6  /

COL1
----------
A

1 row selected.
Elapsed: 00:00:00.01

MYUN@MYDB-C1>>drop table ds1
  2  /

Table dropped.
Elapsed: 00:00:00.03
The time now: 10/30/2019 11:39:36am

我的问题是:

是否可以在不需要子查询的情况下使用分析函数 and 导出值“A”?我知道我可以使用分析函数“ROW_NUMBER”,在 ORDER BY 子句中对结果进行排序,全部在子查询中,然后在外部查询上添加一个 WHERE 子句,我说的是“WHERE RN = 1”,其中“RN"是子查询中使用 ROW_NUMBER 函数的列的别名。

最佳答案

使用带有 KEEP 的聚合函数来获取另一列的最小值:

Oracle 设置:

create table ds1 ( col1, col2 ) AS
  select 'A', 1 from dual
  union all select 'B', 2 from dual
  union all select 'C', 3 from dual
  union all select 'D', 4 from dual
  union all select 'E', 4 from dual
  union all select 'F', 10 from dual;

聚合查询:

SELECT MIN( col1 ) KEEP ( DENSE_RANK FIRST ORDER BY col2 ) AS col1
FROM   ds1

输出:

| COL1 |
| :--- |
| A    |

分析查询:

如果您特别想要一个分析函数,那么:

SELECT col1, col2
FROM   (
  SELECT ds1.*,
         DENSE_RANK() OVER ( ORDER BY col2 ASC ) AS rnk
  FROM   ds1
)
WHERE  rnk = 1

这有一个子查询,但只有一个表扫描。

您可以轻松地将它集成到一个巨大的查询中:

WITH my_huge_query AS (
  <paste your huge query here>
)
SELECT *
FROM   (
  SELECT m.*,
         DENSE_RANK() OVER( ORDER BY col2 ASC ) AS rnk
  FROM   my_huge_query m
)
WHERE  rnk = 1

输出:

COL1 | COL2
:--- | ---:
A    |    1

db<> fiddle here

关于sql - Oracle 12c 解析函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58629122/

相关文章:

mysql - SQL语句中出现错误

php - 在 mysql 列中使用 UNIX 纪元?

php - 如何将数组值与单个变量进行比较?

sql - Oracle 中的 LISTAGG 给出 NULL

c# - hibernate查询使用nolock时出现识别错误

ruby-on-rails - ActiveRecord oracle_enhanced 适配器无法加载 ruby​​-oci8 库

java - 如何修复java中的 “No Dialect mapping for JDBC type: -1”错误

sql - "entity"特定序列

java - Oracle 12c 始终使用 100% CPU

database - 存储过程与匿名 block - 相同的数据,不同的结果