【问题标题】:Changing sql to get rid of windowed functions更改 sql 以摆脱窗口函数
【发布时间】: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,不过问题不大。

任何提示如何解决这个问题?

【问题讨论】:

  • 你能提供样本数据和想要的结果吗?

标签: mysql sql window-functions mysql-5.7


【解决方案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)
    

    【讨论】:

      猜你喜欢
      • 2019-05-12
      • 2014-09-09
      • 1970-01-01
      • 1970-01-01
      • 2021-12-28
      • 1970-01-01
      • 1970-01-01
      • 2010-11-07
      • 2019-03-09
      相关资源
      最近更新 更多