2016-07-12 1 views
0

Моя цель - получить (относительно эффективное) представление MySQL, которое отображает все заказы, которые по-прежнему имеют выдающийся баланс, - указать сумму счета, сумму всех сборов за хранение, общую оплаченную сумму и общую сумму за каждый заказ. Две «счета» - это исходная сумма счета из таблицы заказов, а затем сумма всех сумм хранения (сборов) из таблицы хранения.MySQL: Показывать только заказы, которые имеют баланс при наличии нескольких таблиц счетов для каждого заказа (и нескольких платежей)

В таблице ордеров есть сумма счета-фактуры, все платежи за определенные заказы в таблице платежей и все дополнительные сборы за хранение определенных заказов в таблице хранения (таблицы оплаты и хранения связаны с таблицей заказов на order_id).

Ниже моя схема с примерами данных (а вот SQL fiddle, если это полезно):


CREATE TABLE orders 
(
order_id int NOT NULL AUTO_INCREMENT, 
invoice decimal(10,2), 
PRIMARY KEY (order_id) 
); 


CREATE TABLE payments 
(
payments_id int NOT NULL AUTO_INCREMENT, 
order_id int, 
amount decimal(10,2), 
PRIMARY KEY (payments_id) 
); 

CREATE TABLE storage 
(
storage_id int NOT NULL AUTO_INCREMENT, 
order_id int, 
amount decimal(10,2), 
PRIMARY KEY (storage_id) 
); 


INSERT INTO orders (invoice) 
VALUES ('250'), (NULL), ('150'), ('175.00'), ('175.00'), (NULL); 

INSERT INTO payments (order_id, amount) 
VALUES ('1', '50'), ('3', '50'), ('1', '100'), ('1', '150'), ('4', '100'), ('4', '25'), ('3', '50'); 

INSERT INTO storage (order_id, amount) 
VALUES ('1', '50'), ('4', '25'); 

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


CREATE VIEW accounts_receivable AS 
SELECT 
orders.order_id AS orderid, 
orders.invoice, 
(SELECT sum(amount) from storage WHERE storage.order_id = orders.order_id) AS storagebill, 
coalesce(sum(payments.amount), 0) AS paid, 
coalesce(orders.invoice, 0) + (SELECT coalesce(SUM(storage.amount), 0) FROM storage WHERE storage.order_id = orders.order_id) - (SELECT coalesce(sum(payments.amount), 0) FROM payments WHERE orders.order_id = payments.order_id) AS due 
FROM orders 
LEFT JOIN payments on payments.order_id = orders.order_id 
WHERE 
(coalesce(orders.invoice, 0) + (SELECT coalesce(SUM(storage.amount), 0) FROM storage WHERE storage.order_id = orders.order_id) - (SELECT coalesce(sum(payments.amount), 0) FROM payments WHERE orders.order_id = payments.order_id)) > 0 
GROUP BY orders.order_id 

есть ли способ, чтобы получить эти данные в более эффективный способ? Я предполагаю, что есть несколько способов объединения данных здесь, но я экспериментировал (и искал ответ) безрезультатно. Я относительно новичок в SQL.

+0

Я думаю, что вы опустили оператора сравнения на вас в последний раз, где предложение. –

+0

Если для каждого заказа есть «несколько счетов», не должно быть таблицы счетов, или это то, что плата за хранение? Чем больше я читаю это, тем больше я думаю, что есть лучший способ работать с схемой - но, возможно, я ошибаюсь – MageeWorld

+0

@MageeWorld Да, таблица хранения - это другая таблица счетов. Я попытался подвести итог названия так же хорошо, как мог, но, возможно, это было не совсем точно. Но идея состоит в том, что они должны оплачивать как счет-фактуру, так и любые сборы за хранение, которые они накапливают с течением времени, и все это должно учитываться в сумме, уплаченной и причитающейся суммы (и в предложении WHERE). Это мои таблицы, поэтому я могу изменить таблицы, если это будет иметь больше смысла. –

ответ

0

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

SELECT 
    * 
FROM 
(
    SELECT 
     orderid, 
     invoice, 
     storage, 
     totaldue=invoice+storage, 
     totalpaid=paid, 
     amountdue=(invoice+storage)-paid 
    FROM 
    (
      SELECT 
       orderid=orders.order_id, 
       invoice=orders.invoice, 
       storage= 
       (
        SELECT SUM(amount) FROM storage where order_id=orders.order_id 
       ), 
       paid=SUM(payments.amount) 
      FROM 
       orders 
       LEFT OUTER JOIN payments on payments.order_id=orders.order_id      
      GROUP BY 
       orders.order_id,orders.invoice 
    )AS DETAIL 
)AS SUMMARY 
WHERE 
    SUMMARY.amountdue>0 
+0

К сожалению, поскольку я должен сделать MySQL VIEW из него, MySQL не позволит мне помещать подзапрос в «FROM», поэтому я не думаю, что смогу использовать вышеприведенное решение. Кроме того, для решения того, что вы сказали: вы хорошо разбираетесь в сомнительности схемы. К сожалению, есть некоторые другие ограничения программного обеспечения, которые делают проблематичным иметь одну таблицу для всех «счетов» или даже иметь отдельную таблицу счетов и отдельную таблицу хранения. Сказав это, я очень ценю вашу помощь! –

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