我有以下MySQL表:
function findSame(pos, sortedArr){
for(let i =pos; i<sortedArr.length; i++){
if(sortedArr[i] !== sortedArr[pos]){
return i
}
}
}
function clubSameNumbers(unsortedArr){
let sortedArr = unsortedArr.sort((a,b)=>a-b)
//[ 1, 1, 1, 1, 2, 2, 2, 4, 5, 10, 20, 20, 391, 392, 591 ]
let result = []
for(let i = 0; i < sortedArr.length; i = end){
let start = i
var end = findSame(i, sortedArr)
let arr = sortedArr.slice(i, end)
arr.length > 1 ? result.push(arr) : result.push(...arr)
}
return result
}
console.log(clubSameNumbers([1,2,4,591,392,391,2,5,10,2,1,1,1,20,20]))
//[ [ 1, 1, 1, 1 ], [ 2, 2, 2 ], 4, 5, 10, [ 20, 20 ], 391, 392, 591 ]
我正在尝试编写MySQL查询,该查询将为每个组(公司)返回上次观察(销售)或距上次观察的第n个滞后。
我发现MySQL查询返回每个组的最后观察结果:
firm | Sales | year
A | 100 | 2018
A | 200 | 2017
A | 300 | 2016
B | 400 | 2017
B | 500 | 2016
B | 600 | 2015
C | 700 | 2016
C | 800 | 2015
C | 900 | 2014
但是我不知道如何修改代码以返回最近观察到的滞后值,即:
select *
from (select * from mytable order by `Group`, firm, datum desc) x
group by `Group`
答案 0 :(得分:2)
我认为最通用的方法是使用变量枚举值:
select t.*
from (select t.*,
(@rn := if(@f = t.firm, @rn + 1,
if(@f := t.firm, 1, 1)
)
) as rn
from mytable t cross join
(select @f := '', @rn := 0) params
order by t.firm, t.year desc
) t
where rn = 2;
您的版本有一个致命缺陷:它与group by
一起使用select *
。选择中有未聚合的列,这些列不是group by
键。这是损坏的SQL,几乎在所有数据库中都将失败,并且会使用最新版本的MySQL中的默认设置。
如果意图是“ n”是最近一年之前的年数(很好,由1抵消),则联接可以起作用:
select t.*
from mytable t join
(select firm, max(year) as max_year
from mytable
group by firm
) f
on t.firm = f.firm and t.year = f.max_year - (2 - 1);
答案 1 :(得分:0)
将LAG与MySQL 8中引入的窗口函数一起使用会更容易