2016-04-22 3 views
1

У меня есть таблица заказа, которая выглядит как нижеMySQL Multiple присоединяется к календарной таблице для платежей данных

order_id pre_pay_time pre_pay_amount pre_pay_type final_payment_time final_payment_amount final_payment_type 
============================================================================================================================== 
1   1234123413   10   1    1234123913    25     2  
2   1234123414   25   1    0      100     0  
3   1234123417   75   2    1234125416    155     1   
4   0      0   0    1234126418    60     2   

Здесь клиент может либо сделать предварительный платеж по порядку, а затем оплатить остаток в конце , или они могут просто заплатить полную сумму в конце.

Столбцы pre_pay_time и final_payment_time являются отметками времени UNIX.

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

В настоящее время я могу успешно выводить данные только для суммы окончательного платежа, а также суммы для оплаты наличными и карточками (на основе столбца final_payment_type) за каждый день месяца.

SELECT calendar.datefield AS DATE, IFNULL(SUM(orders.final_payment_amount) , 0) AS total_sales, 
IFNULL(sum(if(final_payment_type=1,orders.final_payment_amount,0)),0)AS total_cash, 
IFNULL(sum(if(final_payment_type=2,orders.final_payment_amount,0)),0)AS total_card, 
count(orders.id) AS order_counter 
FROM orders 
RIGHT JOIN calendar ON (DATE(FROM_UNIXTIME(cast(orders.final_payment_time as signed))) = calendar.datefield) 
WHERE calendar.datefield >= '2016-4-1' AND calendar.datefield <= '2016-4-31' 
GROUP BY DATE 

То, что я надеюсь сделать это расширить запрос, так что я также получить значение сумм за каждый день для pre_pay_amount на основе pre_pay_time. Это позволит мне рассчитать общий доход за день как комбинацию final_payment_amount и pre_pay_amount.

Поскольку предварительная оплата может быть произведена в другой день до окончательного платежа, я считаю, что мне нужно будет сделать еще один JOIN в той же таблице календаря, используя столбец pre_pay_time.

Можно ли сделать это с помощью одного запроса?

+0

- это поле даты DATE без отметки времени на календарной таблице? – cableload

+0

Да, calendar.datefield - ГГГГ-ММ-ДД. Вот почему мне нужно преобразовать unixtimestamps в DATE – dgj

ответ

1

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

SELECT * 
    FROM ( SELECT calendar.datefield AS FinalDate, 
       IFNULL (SUM (orders.final_payment_amount), 0) 
        AS total_final_sales, 
       IFNULL (
        SUM (
         if (final_payment_type = 1, 
          orders.final_payment_amount, 
          0)), 
        0) 
        AS total_final_cash, 
       IFNULL (
        SUM (
         if (final_payment_type = 2, 
          orders.final_payment_amount, 
          0)), 
        0) 
        AS total_final_card, 
       COUNT (orders.id) AS order_final_counter 
      FROM orders 
       RIGHT JOIN calendar 
        ON (DATE (
          FROM_UNIXTIME (
           CAST(orders.final_payment_time AS signed))) = 
          calendar.datefield) 
      WHERE  calendar.datefield >= '2016-4-1' 
       AND calendar.datefield <= '2016-4-31' 
     GROUP BY FinalDate) finalPay, 
     ( SELECT calendar.datefield AS PreDate, 
       IFNULL (SUM (orders.pre_payment_amount), 0) AS total_pre_sales, 
       IFNULL (
        SUM (
         if (pre_payment_type = 1, orders.pre_payment_amount, 0)), 
        0) 
        AS total_pre_cash, 
       IFNULL (
        SUM (
         if (pre_payment_type = 2, orders.pre_payment_amount, 0)), 
        0) 
        AS total_pre_card, 
       COUNT (orders.id) AS order_pre_counter 
      FROM orders 
       RIGHT JOIN calendar 
        ON (DATE (
          FROM_UNIXTIME (
           CAST(orders.pre_payment_time AS signed))) = 
          calendar.datefield) 
      WHERE  calendar.datefield >= '2016-4-1' 
       AND calendar.datefield <= '2016-4-31' 
     GROUP BY PreDate) prePay 
WHERE prePay.PreDate = finalPay.FinalDate 
+0

Это похоже на опрятное решение, я собираюсь пройти тест и посмотреть, насколько он дорог. Отчитается. – dgj

+0

Это работало очень хорошо. Огромное спасибо. Был какой-то небольшой порядок, который был необходим ... У вас не может быть места после объявления CAST, поскольку это порождает ошибку, и GROUP BY должны быть FinalDate и PreDate, а не DATE. Я внес изменения для этого. – dgj

0

Для удобства чтения (ваш пробег на то, что составляет читаемость, может меняться!) Я часто обрабатываю такие вещи, как временная таблица.

То есть, я напишу запрос для вычисления суммы pre_pay_amount и вставьте его в временную таблицу вместе с датой. Затем присоедините эту временную таблицу к этому запросу в дате.

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

+0

Это интересная идея, я ищу временные таблицы. Как бы связать дату, как в запросе, после того, как я создал временную таблицу? – dgj

0

Вы можете сделать это с помощью UNION. Второй запрос будет похож на тот, который у вас есть для окончательных платежей, и используйте столбцы pre_payment. Затем соедините их с UNION и SUM с предложением HAVING. Вот хороший пример того, как это сделать: Sum a union query

Смежные вопросы