获取MySQL中最后X个条目的百分比

获取MySQL中最后X个条目的百分比,mysql,sql,Mysql,Sql,我在MySQLInnoDB中有两个表。第一个是employee表。另一个表是费用表。为简单起见,employee表只包含id和first_name。费用表包含id、员工id、花费金额、预算和创建时间。我想要的是一个查询,返回他们最近登记的X笔开支占预算支出的百分比 因此,给定employee表: | id | first_name ------------------- 1 alice 2 bob 3 mike 4 sally 以及费用表: | id |

我在MySQLInnoDB中有两个表。第一个是employee表。另一个表是费用表。为简单起见,employee表只包含id和first_name。费用表包含id、员工id、花费金额、预算和创建时间。我想要的是一个查询,返回他们最近登记的X笔开支占预算支出的百分比

因此,给定employee表:

| id | first_name
-------------------
   1   alice
   2   bob
   3   mike
   4   sally
以及费用表:

| id | employee_id | amount_spent | budget | created_time
----------------------------------------------------------
   1        1             10          100       10/18
   2        1             50          100       10/19
   3        1             0           40        10/20
   4        2             5           20        10/22
   5        2             10          70        10/23
   6        2             75          100       10/24
   7        3             50          50        10/25
最后3次旅行的查询将返回

|employee_id| first_name | percentage_spent |
--------------------------------------------
     1          alice           .2500 <----------(60/240)
     2          bob             .4736 <----------(90/190)
     3          mike            1.000 <----------(50/50)
|employee_id| first_name | percentage_spent |
--------------------------------------------
     1          alice           .3571 <----------(50/140)
     2          bob             .5000 <----------(85/170)
     3          mike            1.000 <----------(50/50)
最后2次行程的查询将返回

|employee_id| first_name | percentage_spent |
--------------------------------------------
     1          alice           .2500 <----------(60/240)
     2          bob             .4736 <----------(90/190)
     3          mike            1.000 <----------(50/50)
|employee_id| first_name | percentage_spent |
--------------------------------------------
     1          alice           .3571 <----------(50/140)
     2          bob             .5000 <----------(85/170)
     3          mike            1.000 <----------(50/50)

如前所述,如果查询没有返回任何未登记任何费用的员工,那就太好了。提前谢谢

我建议您将创建时间的数据类型转换为日期时间,以获得准确的结果

到目前为止,我假设最近的id表示最近的支出,因为这是样本数据所表明的

但未测试以下查询应能正常工作:

select t2.employee_id,t1.first_name, 
  sum(t2.amount_spent)/sum(t2.budget) as percentage_spent
from employee t1
inner join 
(select temp.* from
        (select e.*,@num := if(@type = employee_id, @num + 1, 1) as row_number,
                    @type := employee_id as dummy 
          from expense e
        order by employee_id,id desc) temp where temp.row_number <= 3   //write value of **n** here.
 ) t2
on t1.id = t2.employee_id               
group by t2.employee_id
;
如果你有任何疑问,请随时提问


希望有帮助

我建议您将创建时间的数据类型转换为日期时间,以获得准确的结果

到目前为止,我假设最近的id表示最近的支出,因为这是样本数据所表明的

但未测试以下查询应能正常工作:

select t2.employee_id,t1.first_name, 
  sum(t2.amount_spent)/sum(t2.budget) as percentage_spent
from employee t1
inner join 
(select temp.* from
        (select e.*,@num := if(@type = employee_id, @num + 1, 1) as row_number,
                    @type := employee_id as dummy 
          from expense e
        order by employee_id,id desc) temp where temp.row_number <= 3   //write value of **n** here.
 ) t2
on t1.id = t2.employee_id               
group by t2.employee_id
;
如果你有任何疑问,请随时提问

希望有帮助

如果您正在使用,则可以使用窗口功能

 SELECT employee_id, first_name, sliding_sum_spent/sliding_sum_budget
 FROM
 (
  SELECT employee_id, first_name,
   SUM(amount_spent) OVER (PARTITION BY employee_id
                        ORDER BY created_time
                        RANGE BETWEEN 3 PRECEDING AND 0 FOLLOWING) AS sliding_sum_spent,
   SUM(budget) OVER (PARTITION BY employee_id
                        ORDER BY created_time
                        RANGE BETWEEN 3 PRECEDING AND 0 FOLLOWING) AS sliding_sum_budget,
   COUNT(*) OVER (PARTITION BY employee_id
                        ORDER BY created_time DESC) rn
  FROM expense
  JOIN employee On expense.employee_id = employee.id 
 ) t
 WHERE t.rn = 1
正如Harshil所提到的,根据创建时间的行顺序可能会有问题,因此,最好使用日期类型。

如果您正在使用,则可以使用窗口功能

 SELECT employee_id, first_name, sliding_sum_spent/sliding_sum_budget
 FROM
 (
  SELECT employee_id, first_name,
   SUM(amount_spent) OVER (PARTITION BY employee_id
                        ORDER BY created_time
                        RANGE BETWEEN 3 PRECEDING AND 0 FOLLOWING) AS sliding_sum_spent,
   SUM(budget) OVER (PARTITION BY employee_id
                        ORDER BY created_time
                        RANGE BETWEEN 3 PRECEDING AND 0 FOLLOWING) AS sliding_sum_budget,
   COUNT(*) OVER (PARTITION BY employee_id
                        ORDER BY created_time DESC) rn
  FROM expense
  JOIN employee On expense.employee_id = employee.id 
 ) t
 WHERE t.rn = 1

正如Harshil所提到的,根据创建时间的行顺序可能会有问题,因此,最好使用日期类型。

感谢数据类型建议。您的查询返回的这个版本的MySQL还不支持“LIMIT&IN/ALL/ANY/SOME子查询”。有简单的解决方法吗?请尝试编辑后的答案并检查演示。现在应该可以了。谢谢你的数据类型建议。您的查询返回的这个版本的MySQL还不支持“LIMIT&IN/ALL/ANY/SOME子查询”。有简单的解决方法吗?请尝试编辑后的答案并检查演示。现在应该可以了。