sql - HAVING 子句中的 WINDOW 函数替代

标签 sql oracle subquery greatest-n-per-group having-clause

我正在尝试获取每个产品的最早处理日期,如下所示:

select prod_id, prod_name, prod_date, min(prod_date) over (partition by prod_id) as min_prod_date
from dim_product
where prod_name in ('xxx', 'yyy', 'zzz')
having prod_date = min_prod_date

这给了我错误:

ORA-00904: "min_prod_date": invalid identifier

所以我尝试在having子句中使用min()函数,这给了我错误:

ORA-30483: window functions are not allowed here

作为替代方案,我修改了我的查询,如下所示:

with temp as(
select prod_id, prod_name, prod_date, min(prod_date) over (partition by prod_id) as min_prod_date
    from dim_product
    where prod_name in ('xxx', 'yyy', 'zzz')
    having prod_date = min_prod_date))
select * from temp where prod_date = min_prod_date

这是正确的做事方式还是有其他有效的方法?

最佳答案

一种方法在子查询中使用rank():

select *
from (
    select 
        prod_id, 
        prod_name, 
        prod_date, 
        rank() over(partition by prod_id order by prod_date) rn
    from dim_product
    where prod_name in ('xxx', 'yyy', 'zzz')
) t
where rn = 1

作为替代方案,您可能还需要考虑使用相关子查询进行过滤:

select prod_id, prod_id, prod_date
from dim_product d
where d.prod_name in ('xxx', 'yyy', 'zzz') and d.prod_date = (
    select min(d1.prod_date)
    from dim_product d1
    where d1.prod_id = d.prod_id and d1.prod_name in ('xxx', 'yyy', 'zzz')
)

为了提高后一个查询的效率,您需要在 (prod_name, prod_id, prod_date) 上建立索引。

关于sql - HAVING 子句中的 WINDOW 函数替代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60290402/

相关文章:

mysql - 使用子查询和分组依据计算每个国家/地区每日 DAU 平均值

mysql - 在 MySQL 中使用子查询进行更新

mysql - 避免查询中出现重复并将所有重复行设为空白

php - MySQL 选择高效的第一行和最后一行

oracle - 当您尝试避免使用魔数(Magic Number)来表示字符串长度时,clob 类型是否在 PL/SQL 代码中使用了不好的做法?

sql - 在 Oracle SQL 语句中使用分号

sql - 从 Postgres 中的子查询构造值的 ARRAY 并在 WHERE 子句中使用它

MySql 用 SUM() 缓慢连接结果

mysql - 如何构建这个复杂的sql?

sql - 解码语句 : strange behaviour