查询结束时的多个窗口定义
Posted
技术标签:
【中文标题】查询结束时的多个窗口定义【英文标题】:Multiple window definitions at the end of the query 【发布时间】:2019-05-05 17:43:12 【问题描述】:在 Oracle 中另一种编写窗口函数的方法是这样的:
Select a
first_value(b) over w,
first_value(c) over w
from table
window w as (partition by d order by e)
当我必须计算同一分区上的多个列时,我发现这非常有用。但是,我想知道在查询结束时是否可以有多个窗口定义。
Select a
first_value(b) over w,
first_value(c) over w,
first_value(h) over t,
first_value(i) over t
from table
window w as (partition by d order by e)
window t as (partition by f order by g)
我认为代码变得更容易理解,而不是在第二个窗口定义 (t) 的每一列的 from 中编写分区定义。
问候
【问题讨论】:
你尝试的时候发生了什么? 报错了,不知道是不可能的,还是我写错了 我认为你最好的选择是模拟/模拟 mysql 8.0 名称窗口是在 Oracle 中使用公用表表达式 (CTE) (WITH <name> AS (...)
语法),但我非常怀疑语法是否会那么简单就像你可能需要一个 JOIN 之后的语法一样
这不是远程Oracle语法。
【参考方案1】:
很确定这是 MySQL 8 的语法,你把它弄混了。 我想你看到这个manual page 是关于 MySQL 8 数据库而不是 Oracle 数据库,因为 MySQL 数据库也归 Oracle 公司所有。
查询
SELECT
COUNT(a."profit") OVER w
FROM
a
WINDOW w as (PARTITION BY a."year")
在 Oracle 数据库上将导致错误 ORA-00923: FROM keyword not found where expected
请参阅 demo
在哪里
SELECT
COUNT(a.profit) OVER w
FROM
a
WINDOW w as (PARTITION BY a.year)
在 MySQL 8.0 上可以正常工作,请参阅 demo
【讨论】:
好的,但是有可能做这样的事情吗,我试过了,但我总是收到一条错误消息。也许(如果可能的话)我写错了【参考方案2】:虽然ANSI SQL 2003正式将窗口函数引入SQL语言作为标准并且确实支持WINDOW
子句,但实际上只有少数DBMS将该子句集成到他们的方言中,包括Postgres、Sybase Anywhere、SQLite,现在最近mysql。其他专业,Oracle、DB2 和 SQL Server,似乎不支持WINDOW
子句。
Postgres docs
Sybase Anywhere docs
SQLite docs
因此,您需要为 Oracle 中的每次聚合使用重写窗口。
【讨论】:
但至少你有窗口函数。 MS Access 2019(世界十大 DBMS 之一)仍然不支持窗口函数、CTE 或其他当前标准。请加入投票、分享、评论我的ticket 到 Access 团队以更新其方言。【参考方案3】:语法是:
WINDOW window_name AS (window_spec)
[, window_name AS (window_spec)] ...
Windows 之间需要一个逗号:
Select a
first_value(b) over w,
first_value(c) over w,
first_value(h) over t,
first_value(i) over t
from table
window w as (partition by d order by e), t as (partition by f order by g)
【讨论】:
这个是正确答案,根据实际问题,去掉第二个“window”关键字,加一个逗号以上是关于查询结束时的多个窗口定义的主要内容,如果未能解决你的问题,请参考以下文章
1.19.7.Table APISQL数据类型保留关键字查询语句指定查询执行查询语法操作符无排名输出优化去重分组窗口时间属性选择分组窗口的开始和结束时间戳模式匹配