Sql 计算相同起始和结束目的地的总报销额

Sql 计算相同起始和结束目的地的总报销额,sql,Sql,只有当员工在整个旅程中的起点和终点相同时,我才必须向员工报销金额。也就是说,如果起点是A,然后目的地是B,在行程的一段,第二段有起点B或C,但目的地是B 下面是一个例子 Employee Name|Employee ID|From station|To station|Amount -------------|-----------|------------|----------|--------- Jon | 1 | BLR | HYD

只有当员工在整个旅程中的起点和终点相同时,我才必须向员工报销金额。也就是说,如果起点是A,然后目的地是B,在行程的一段,第二段有起点B或C,但目的地是B

下面是一个例子

Employee Name|Employee ID|From station|To station|Amount
-------------|-----------|------------|----------|---------
    Jon      |    1      |    BLR     |    HYD   | 1000
    Jon      |    1      |    HYD     |    DEL   | 1000
    Russ     |    2      |    BLR     |    DEL   | 1500
    Russ     |    2      |    DEL     |    BLR   | 1500
    Raj      |    3      |    BLR     |    DEL   | 1500
    Raj      |    3      |    DEL     |    HYD   | 1300
    Raj      |    3      |    Hyd     |    JAI   | 1200
我只希望我的SQL查询返回RUS,因为RUS的开始和结束目标是相同的。 . 谁能帮我写下这个问题


提前感谢。

不幸的是,要真正回答您的问题,您需要一列指定行的顺序

近似值是“从”和“到”值的集合相同。您可以通过计数来完成此操作:

select t.*
from (select employeeid, count(distinct fromstation) as num_from,
             count(distinct tostation) as numto,
             count(*) as cnt
      from t
      group by employeeid
     ) t join
     t tfrom
     on tfrom.employeeid = t.employeeid join
     t tto
     on tto.employeeid = t.employeeid and
        tto.tostation = tfrom.fromstation
where t.numfrom = t.numto and t.numfrom = t.cnt
group by t.employeeid, t.cnt
having t.cnt = count(*);

这并不精确,但它适用于对数据的合理假设,例如不多次返回同一站点和连续行程。

我认为您需要添加“行程标识符”,因为在添加记录时,您将无法判断行程属于哪个行程。您还需要对行程进行排序,否则您如何知道起点和最终目的地

您还可以尝试规范化您的数据库,这将简化围绕查询的推理

我想出了这样的办法:

create table employee
(
    id   serial primary key,
    name varchar not null
);

create table journey
(
    id       serial primary key,
    employee integer not null references employee (id) on delete cascade
);

create table trip
(
    id           serial primary key,
    journey      integer     not null references journey (id) on delete cascade,
    from_station varchar     not null,
    to_station   varchar     not null,
    trip_date    timestamptz not null,
    amount       real        not null
);
然后,您可以一次性获得reimurse的员工、行程和金额:

select e.id           as emp_id,
       e.name         as employee,
       j.id           as journey_id,
       st.trip_date   as trip_start,
       et.trip_date   as trip_end,
       sum(wt.amount) as amount
from employee e
         join journey j on e.id = j.employee
         join trip st on j.id = st.journey
         join trip et on j.id = et.journey
         join trip wt on j.id = wt.journey
where st.from_station = et.to_station
  and st.trip_date = (select min(t.trip_date) from trip t where t.journey = j.id)
  and et.trip_date = (select max(t.trip_date) from trip t where t.journey = j.id)
group by e.id, j.id, e.name, st.trip_date, et.trip_date;

这里有一个db提琴可以玩:

用您正在使用的数据库标记您的问题。此外,SQL表表示无序集。在没有排序列的情况下,没有明显的方法来确定员工旅程的开始和结束位置。如下所述,您缺少了一个列,您可以称之为“旅程”列。我认为您必须在带有t.cnt的
上添加一个虚拟聚合。