Вложенный оператор SQL не вычисляет SUM, как ожидалось

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

У меня есть 3 таблицы регистрации, события и таблица платежей. Регистрации — это отдельные транзакции, события — это информация о том, на что они подписались, а платежи — это платежи, сделанные для событий.

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

select 
  sum(`reg_amount`) as total, 
  event_name, 
  event_startdate, 
  (
    select sum(payment_amount) as paid 
    from registrations 
    group by events.event_id
  ) pay
FROM registrations 
  left join events 
    on events.event_id = registrations.event_id
  left join payments 
    on payments.event_id = events.event_id
group by registrations.event_id

person Joe    schedule 02.04.2013    source источник
comment
Не могли бы вы уточнить, что такое reg_amount?   -  person atw13    schedule 02.04.2013
comment
reg_amount происходит от registrations? Если да, то я не понимаю, зачем вам нужно соединение с payments - и вам, вероятно, нужно предложение where в подзапросе "pay", чтобы ограничить то, что возвращается к соответствующему событию.   -  person AjV Jsy    schedule 02.04.2013
comment
Пожалуйста, не могли бы вы включить в вопрос структуру таблиц для ваших таблиц? На данный момент можно только догадываться, какое поле из какой таблицы или отношения между таблицами.   -  person    schedule 02.04.2013


Ответы (1)


Во-первых, вы должны использовать псевдонимы, чтобы мы знали, откуда берутся все поля. Я предполагаю, что payment_amount происходит из таблицы payments, а не из registrations.

Если это так, ваш подзапрос суммирует платежи из внешней таблицы для каждой строки регистраций. Вероятно, это не то, что вы хотите.

Я думаю, вы хотите что-то вроде этого:

select sum(`reg_amount`) as total, 
       e.event_name, 
       e.event_startdate, 
       p.TotPayements
FROM registrations r left join
     events e
     on e.event_id = r.event_id left join
     (select event_id, sum(payment_amount) as TotPayments
      from payments
      group by event_id
     ) p
     on p.event_id = e.event_id
group by r.event_id;

Идея состоит в том, чтобы агрегировать платежи на самом низком уровне, чтобы избежать дублирования, вызванного присоединением. То есть агрегировать до присоединения.

Это предположение относительно правильного SQL, но оно должно поставить вас на правильный путь.

person Gordon Linoff    schedule 02.04.2013