SQL SUM operation of multiple subqueries

后端 未结 6 810
清歌不尽
清歌不尽 2021-01-12 09:52

i have the following mysql database table designed,

ticket(id, code, cust_name);
passenger(id, ticket_id, name, age, gender, fare);
service(id, passenger_id,         


        
相关标签:
6条回答
  • 2021-01-12 10:34

    What about this?

    SELECT 
        SUM(fare) as total_fare,
        SUM(cost) as total_cost as total_service_cost
    FROM
        ticket
    JOIN passenger ON passenger.ticket_id = ticket.id
    JOIN service ON passenger.id = service.passenger_id
    

    If you need to sum for each ticket then add GROUP BY ticket.id

    0 讨论(0)
  • 2021-01-12 10:35

    First of all in your current table schema you have no way to distinguish between services that have been sold to the same passenger in different tickets. Therefore you have no way to correctly calculate total_cost per ticket. You have to have ticket_id in your service table.

    Now, if you were to have a ticket_id in service table then a solution with a correlated subqueries might look like

    SELECT t.*,
           (SELECT SUM(fare) 
              FROM passenger
             WHERE ticket_id = t.id) total_fare,
           (SELECT SUM(cost) 
              FROM service
             WHERE ticket_id = t.id) total_cost
      FROM ticket t
    

    or with JOINs

    SELECT t.id, 
           p.fare total_fare,
           s.cost total_cost
    FROM ticket t LEFT JOIN 
    (
      SELECT ticket_id, SUM(fare) fare
        FROM passenger
       GROUP BY ticket_id
    ) p 
      ON t.id = p.ticket_id LEFT JOIN 
    (
      SELECT ticket_id, SUM(cost) cost
        FROM service
       GROUP BY ticket_id
    ) s
      ON t.id = s.ticket_id
    

    Note: Both queries take care of the fact that passenger can have multiple services per ticket or no services at all.


    Now with your current schema

    SELECT t.*,
           (SELECT SUM(fare) 
              FROM passenger
             WHERE ticket_id = t.id) total_fare,
           (SELECT SUM(cost) 
              FROM service s JOIN passenger p
                ON s.passenger_id = p.id
             WHERE p.ticket_id = t.id) total_cost
      FROM ticket t
    

    and

    SELECT t.id, 
           p.fare total_fare,
           s.cost total_cost
    FROM ticket t LEFT JOIN 
    (
      SELECT ticket_id, SUM(fare) fare
        FROM passenger
       GROUP BY ticket_id
    ) p 
      ON t.id = p.ticket_id LEFT JOIN 
    (
      SELECT p.ticket_id, SUM(cost) cost
        FROM service s  JOIN passenger p
          ON s.passenger_id = p.id
       GROUP BY p.ticket_id
    ) s
      ON t.id = s.ticket_id
    


    Just to get a grand total per ticket

    SELECT t.*,
           (SELECT SUM(fare) 
              FROM passenger
             WHERE ticket_id = t.id) +
           (SELECT SUM(cost) 
              FROM service s JOIN passenger p
                ON s.passenger_id = p.id
             WHERE p.ticket_id = t.id) grand_total
      FROM ticket t
    

    or

    SELECT t.id, 
           p.fare + s.cost grand_total
    FROM ticket t LEFT JOIN 
    (
      SELECT ticket_id, SUM(fare) fare
        FROM passenger
       GROUP BY ticket_id
    ) p 
      ON t.id = p.ticket_id LEFT JOIN 
    (
      SELECT p.ticket_id, SUM(cost) cost
        FROM service s  JOIN passenger p
          ON s.passenger_id = p.id
       GROUP BY p.ticket_id
    ) s
      ON t.id = s.ticket_id
    
    0 讨论(0)
  • 2021-01-12 10:43

    How about this?

    with fares as(
    select p.id id, p.ticket_id ticket_id, sum(coalesce(s.cost,0)) cost
      from passenger p left outer join service s
           on p.id = s.passenger_id
     group by p.id, p.ticket_id)
    select q.ticket_id, sum(f.cost), sum(q.fare), sum(f.cost + q.fare)
      from fares f inner join passenger q
           on f.id = q.id
     group by q.ticket_id;
    
    0 讨论(0)
  • 2021-01-12 10:44

    You can just join the three tables together, then you can do the SUMs directly without the subselect. You'll need to use GROUP BY to group by ticket.id if you want it per ticket.

    Something like:

    SELECT t.id, SUM(p.fare) AS total_far, SUM(s.cost) AS total_cost
    FROM 
        ticket t, passenger p, service s
    WHERE t.id = p.ticket_id AND s.passenger_id = p.id 
    GROUP BY t.id;
    
    0 讨论(0)
  • 2021-01-12 10:49
    select
        t.code,
        sum(p.fare) as total_fare,
        sum(s.cost) as total_cost
    from ticket as t
        inner join passenger as p on p.ticket_id = t.id
        inner join service as s on s.passenger_id = p.id
    group by t.code
    
    0 讨论(0)
  • 2021-01-12 10:52
    SELECT 
        SUM(fare) as total_fare,
        SUM(cost) as total_service_cost
    FROM
        ticket
    left join passenger ON ticket.id = passenger.ticket_id
    left join service ON passenger.id = service.passenger_id
    
    0 讨论(0)
提交回复
热议问题