2013-08-13 3 views
2

я следующий MySQL таблицы базы данных, разработанная,SQL операция SUM нескольких подзапросов

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 

Хотя, результат получает общее количество пассажиров тарифа, как total_fare, но по стоимости услуг, она суммирует и возвращает только общую стоимость обслуживания первого пассажира.

Я думаю, что мне нужно еще несколько гнездящихся запросов, нужна помощь и, если возможно, пожалуйста, как я могу получить результат в виде итогового суммирования как общей стоимости проезда, так и стоимости обслуживания.

OK вот SQL вставка Постулаты уточнить,


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.

Спасибо! :)

+1

Как вы проводите различие между услугами, которые были проданы одному и тому же пассажиру в разных билетах? Похоже, что 'ticket_id' отсутствует в таблице' service' ... – peterm

+0

Peterm здесь используется служебная таблица, для хранения предмета обслуживания, купленного пассажиром, и связана с пассажирским столом с помощью ограничения доступа для пассажира-пассажира. –

ответ

7

Прежде всего, в вашей текущей схемы таблицы не имеют возможности проводить различие между услугами, которые были проданы в тот же пассажир в разных билетах. Поэтому у вас нет возможности правильно рассчитать total_cost за билет. Вы должны иметь ticket_id в таблице service.

Теперь, если вы должны были иметь в service столе ticket_id затем раствор с коррелированных подзапросов может выглядеть

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 сек

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 
+0

@DipendraGurung См. Обновленный ответ для решений для вашей текущей схемы таблиц – peterm

+0

Спасибо! @Peterm, одна вещь, которую я хотел бы добавить больше, как я могу добавить эти два подзапроса, чтобы получить одно поле в виде grand_total? Благодаря! за ваше время. :) –

+0

@DipendraGurung Вам нужно просто огромное количество, или вы хотите увидеть total_fare, total_cost и grand_total? – peterm

2

Вы можете просто присоединиться к трем таблицам вместе, тогда вы можете напрямую использовать SUM без подзапроса. Вам нужно будет использовать GROUP BY для 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; 
+0

Спасибо! Пробел, когда я запускаю ваш запрос, total_cost был правильно суммирован, но total_fare неверен! –

+0

@DipendraGurung Общая стоимость проезда рассчитывается так же, как и ваш вопрос, поэтому я не вижу, как это может быть неправильно. –

+0

Я не думаю, что этот или любой другой ответ, размещенный здесь, работает. Если у пассажира имеется несколько услуг, при расчете тарифа он будет добавляться столько раз, сколько количество услуг. – Noel

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

+0

является двойным 'как' разрешено в 3-й строке вашего запроса? У меня возникла ошибка при выполнении этого запроса. –

+0

Извините, что просто набрав ошибку – StanislavL

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 
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 
+0

Я думаю, что вам не хватает 'group by' :) –

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; 
Смежные вопросы