如何获取员工名单以及他们的差旅费用

时间:2019-06-18 07:19:25

标签: sql oracle

我想获得一个雇员姓名列表以及他们的旅行报销金额。

规则:员工只有在回程中的出发地与目的地相同时才有资格获得报销。

输入:表名称:报销

  Name      From_station      To_station         Amount
    Hari    Bengaluru         Hyderabad    2500
    Hari    Hyderabad         Bengaluru    2600
    Raju    Chennai           Pune         3400
    Raju    Pune              Hyderabad    2000
    Kiran   Kerala            Chennai      2300
    Kiran   Chennai           Kerala       3200

输出:

Name        Reimbursement_amount
Hari        5100
Kiran       5500

查询

select p.name, amount 
      from(select name,
                  min(from_station) as from_station,
                  min(to_station) as to_station,
                  sum(amount) as amount 
           from reimbursement r1 group by name) p 
where p.from_station = p.to_station 
order by name;

我在正确的轨道上吗?

3 个答案:

答案 0 :(得分:1)

您可以使用交叉联接来检查特定用户的行之间的目的地,并仅使用匹配的逻辑来保留记录。

注意:如果您可以使用User_id代替Name(名称)更好,因为可能有多个用户使用相同的名称。

SELECT A.Name, SUM(A.Amount) Reimbursement_amount
FROM Reimburment A
CROSS JOIN Reimburment B
WHERE A.From_station = B.To_station AND A.To_station = B.From_station
AND A.Name = B.Name
GROUP BY A.Name

答案 1 :(得分:0)

您可以使用EXISTS做到这一点:

select 
  t.Name, 
  sum(t.Amount) Reimbursement_amount
from Reimburment t
where exists (
  select 1 from Reimburment
  where Name = t.Name and From_station = t.To_station and To_station = t.From_station
)
group by t.Name

请参见demo
结果:

| Name  | Reimbursement_amount |
| ----- | -------------------- |
| Hari  | 5100                 |
| Kiran | 5500                 |

答案 2 :(得分:-1)

mosdt dbms支持分析函数first_value和last_value我曾经用过明智的方法来命名from station的第一个值和to station的最后一个值,并将它们进行比较以进行选择以获得重新入侵

 with reimbursement as
(
select 'Hari' as name, 'Bengaluru' as From_station , 'Hyderabad' as To_station, 2500 as amount
union all
select 'Hari','Hyderabad','Bengaluru',2600
union all
select 'Raju','Chennai','Pune',3400
union all
select 'Raju','Pune','Hyderabad',2000 
union all
select 'Kiran','Kerala','Chennai',2300
union all
select 'Kiran','Chennai','Kerala',3200
),cte as
(
select *,row_number()over(partition by name order by From_station) rn
from reimbursement
), cte1 as
 (select name,amount,
 FIRST_VALUE(From_station) over(partition by name order by rn) as f,
 LAST_VALUE(To_station) over(partition by name  order by rn desc) t
 from cte
 )select name , sum(amount) AS TOTAL 
 FROM reimbursement WHERE name IN (
 select name 
 from cte1 where f=t
 ) GROUP BY NAME

enter image description here

name    TOTAL
Hari    5100
Kiran   5500