更改 sql 以摆脱窗口函数
Posted
技术标签:
【中文标题】更改 sql 以摆脱窗口函数【英文标题】:Changing sql to get rid of windowed functions 【发布时间】:2020-10-01 10:24:11 【问题描述】:我正在尝试在远程 mysql 数据库上创建视图,不幸的是,安装的版本 (5.7) 似乎不支持窗口功能。一切都在我的本地数据库上运行,但现在我有点卡住了。
这是之前的代码:
create or replace view my_view as
(
with a as
(select a.*, DENSE_RANK() over (partition by SHOP order by TIMESTAMP(LOAD_TIME) DESC) rn
from my_table as a)
select row_number() OVER () as id, SHOP, LOAD_TIME from a WHERE a.rn = 1
);
Mysql 5.7 也不支持 CTE,不过问题不大。
任何提示如何解决这个问题?
【问题讨论】:
你能提供样本数据和想要的结果吗? 【参考方案1】:更换dense_rank()
非常简单。但是,替换row_number()
更加困难。 MySQL 不允许视图中的变量。不幸的是,这也使您对行号的子查询效率低下:
select (select count(distinct shop)
from mytable t2
where t2.shop <= t.shop
) as id,
shop, load_time
from mytable t
where t.load_time = (select max(t2.load_time) from mytable t2 where t2.shop = t.shop);
或者,如果您只有这两列,请使用聚合:
select (select count(distinct shop)
from mytable t2
where t2.shop <= t.shop
) as id,
shop, max(load_time) as load_time
from mytable t
group by shop;
这不是有效的。在一个简单的查询中,您可以使用变量:
select (@rn := @rn + 1) as id,
shop, load_time
from mytable t cross join
(select @rn := 0) params
where t.load_time = (select max(t1.load_time) from mytable t1 where t1.shop = t.shop);
如果性能是一个问题,那么您可能希望创建一个表而不是视图,并使用触发器使其保持最新状态。
【讨论】:
【参考方案2】:您可以使用相关子查询处理过滤部分:
create or replace view my_view as
select shop, load_time
from mytable t
where t.load_time = (select max(t1.load_time) from mytable t1 where t1.shop = t.shop)
【讨论】:
以上是关于更改 sql 以摆脱窗口函数的主要内容,如果未能解决你的问题,请参考以下文章