我设计了以下mysql数据库表,
ticket(id, code, cust_name);
passenger(id, ticket_id, name, age, gender, fare);
service(id, passenger_id, item, cost);
一张票可以有很多乘客,每位乘客可以购买多种服务。我想要的是得到每张票的总成本。
我试过以下的sql,
SELECT
SUM(fare) as total_fare,
(SELECT SUM(cost) as total_cost FROM services WHERE passenger.id = services.passenger_id) as total_service_cost
FROM
ticket
JOIN passenger ON passenger.ticket_id = ticket.id
虽然,结果是乘客票价总额为总票价但是对于服务费用,它只汇总并返还第一位乘客的总服务费用。
我认为我需要更多的查询嵌套,需要帮助,如果可能的话,我怎么能得到结果总计为乘客票价和服务成本总计。
好的,这里是sql insert statment来澄清,
INSERT INTO `ticket` (`id`, `code`, `cust_name`) VALUES
(1, 'TK01', 'Dipendra Gurung');
INSERT INTO `passenger` (`id`, `ticket_id`, `name`, `age`, `gender`, `fare`) VALUES
(1, 1, 'John', '28', 'M', 120),
(2, 1, 'Kelly', '25', 'F', 120);
INSERT INTO `services` (`id`, `passenger_id`, `item`, `cost`) VALUES
(1, 1, 'S1', 30),
(2, 1, 'S2', 50),
(3, 2, 'S3', 50);
我想获得机票'TK01'的总费用(包括总票价和服务总额)。 sql必须返回总票价为120 + 120 = 240,总服务为30 + 50 + 50 = 130。
谢谢! :)
答案 0 :(得分:11)
首先,在您当前的表架构中,您无法区分已在不同票证中销售给同一乘客的服务。因此,您无法正确计算每张票的total_cost
。您必须在ticket_id
表中添加service
。
现在,如果您在ticket_id
表中有service
,则具有相关子查询的解决方案可能看起来像
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
或JOIN
s
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
注意:两个查询都会考虑到乘客每张票可以拥有多项服务或根本没有服务这一事实。
现在使用您当前的架构
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
和
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
<小时/> 只需获得每张票的总票数
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
或
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
答案 1 :(得分:2)
您可以将三个表连接在一起,然后您可以直接执行SUM而不使用子选择。如果您需要每张票,您需要使用GROUP BY
按ticket.id进行分组。
类似的东西:
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;
答案 2 :(得分:2)
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
答案 3 :(得分:0)
这个怎么样?
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
如果您需要为每张票证求和,请添加GROUP BY ticket.id
答案 4 :(得分:0)
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
答案 5 :(得分:0)
这个怎么样?
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;