如何在 MySQL 8(如 MSSQL)上使用表达式作为 LAG() 第二个参数?
Posted
技术标签:
【中文标题】如何在 MySQL 8(如 MSSQL)上使用表达式作为 LAG() 第二个参数?【英文标题】:How to use expression as LAG() second parameter on MySQL 8 (like MSSQL)? 【发布时间】:2019-11-06 15:38:13 【问题描述】:我正在尝试迁移此 SQL SERVER 查询:
SELECT year, sales,
LAG(year-2, 2*(SELECT MIN(sales) FROM product_sales), sales/2.0 ) OVER (ORDER BY year) AS no_sense
FROM product_sales;
dbfiddle link
到 MySQL 8(相同的查询):
dbfiddle link
不幸的是,我收到了这个错误:
您的 SQL 语法有错误;检查手册 对应于您的 mysql 服务器版本,以便使用正确的语法 '*(SELECT MIN(sales) FROM product_sales), sales/2.0) OVER (ORDER) 附近 BY year) AS no_' 在第 2 行
是否可以将此查询“移植”到 mysql?
提前致谢!
【问题讨论】:
你想完成什么?这在任何数据库中似乎都没有用。 这只是授权框架orm的一个例子 我认为您想使用 LAG() 但不在窗口函数中。您能描述一下您要计算的内容吗/ 我想从 sqlserver 得到同样的结果 【参考方案1】:注意:此答案基于 Vignesh Kumar A 的 answer。 那么为什么 MySQL 8 不支持 SQL Server 语法已经在他的回答中得到了充分的解释,我选择不解释它。
在 MySQL 8 中,您需要从中进行动态 SQL 查询,因为 LAG()
的偏移量参数不支持 SQL 表达式..
SET @sql = CONCAT("
SELECT
year
, sales
, LAG(year-2, ",(SELECT FLOOR(MIN(sales)) FROM product_sales),", sales/2.0 ) OVER (ORDER BY year) AS no_sense
FROM product_sales;
");
PREPARE q FROM @sql;
EXECUTE q;
注意: FLOOR()
可以修复 19874.00
不给出延迟功能的错误。
在场外,您可以重写SET @sql := CONCAT("..")
部分different,只需使用您最了解的写作风格。
结果
| year | sales | no_sense |
| ---- | ----- | -------- |
| 2017 | 55000 | 27500 |
| 2017 | 78000 | 39000 |
| 2017 | 49000 | 24500 |
| 2017 | 32000 | 16000 |
| 2018 | 41000 | 20500 |
| 2018 | 89651 | 44825.5 |
| 2018 | 19874 | 9937 |
| 2018 | 32562 | 16281 |
| 2019 | 87456 | 43728 |
| 2019 | 75000 | 37500 |
| 2019 | 96500 | 48250 |
| 2019 | 85236 | 42618 |
见demo
之所以有效,是因为PREPARE q FROM @sql;
会生成此 SQL。 (Vignesh Kumar A 答案)
SELECT
year
, sales
, LAG(year-2, 19874, sales/2.0 ) OVER (ORDER BY year) AS no_sense
FROM product_sales;
【讨论】:
非常感谢!我希望这个问题可以在未来几年 MySQL 8 更流行时对人们有所帮助。 “我希望这个问题可以在 MySQL 8 更受欢迎的未来几年对人们有所帮助。” 也许@celsowm 仍然是 Gordon Linoff 的评论 “你想做什么完成?这在任何数据库中似乎都没有用。” 关于你的问题是非常有效的,这并不是很有用..【参考方案2】:这是因为 LAG
函数中的 offset
参数。在MYSQL
中,偏移量将不接受表达式或列,它只接受正数,而MSSQL
将接受除负数之外的所有值。
MYSQL
offset
- offset
是从当前行返回的行数,从中获取值。偏移量必须为零或文字正整数。如果 offset 为零,则 LAG() 函数计算当前行的表达式。如果不指定偏移量,则 LAG() 函数默认使用一个。
MSQSQL
offset
- 从当前行返回的行数,从中获取值。如果未指定,default
为 1。offset 可以是列、子查询或其他表达式,其计算结果为正整数或可以隐式转换为 bigint。 offset 不能为负值或解析函数。
也许你可以尝试最大数量的相同查询。
SELECT year, sales,
LAG(year-2, 19874, sales/2.0 ) OVER (ORDER BY year) AS no_sense
FROM product_sales;
FIDDLE
【讨论】:
太可惜了,我试过用@variable但是结果是空的:dbfiddle.uk/…以上是关于如何在 MySQL 8(如 MSSQL)上使用表达式作为 LAG() 第二个参数?的主要内容,如果未能解决你的问题,请参考以下文章