【发布时间】:2016-07-12 16:26:15
【问题描述】:
我的目标是获得一个(相对高效的)MySQL 视图,该视图显示所有仍有未结余额的订单——显示发票金额、所有存储费用的总和、支付的总金额以及每个订单的到期总额。这两个“账单”是orders表中的原始发票金额,然后是存储表中所有存储金额(费用)的总和。
订单表中有发票金额,支付表中有特定订单的所有付款,存储表中有特定订单的所有额外存储费用(支付和存储表与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 比较陌生。
【问题讨论】:
-
我认为您在最后一个 where 子句中省略了比较运算符。
-
如果每个订单有“多张账单”——不应该有账单表吗,或者这就是存储费?我读得越多,我就越认为有更好的方法来处理模式 - 但也许我错了
-
@MageeWorld 是的,存储表是另一个“账单”表。我试图尽可能地总结标题,但也许它不太准确。但想法是,他们必须同时支付发票和随着时间累积的任何仓储费,并且这些费用都应计入已付金额和到期金额(以及 WHERE 条款)。它们是我的桌子,所以如果这样更有意义的话,我可以更换桌子。
-
@lrb 是的,关于需要运算符“> 0”的 WHERE 子句是正确的。不知何故,当我简化查询时,它并没有出现,但我现在已经改变了它。谢谢!
-
理想情况下,您的设计应该生成一个简单的订单项金额汇总,订单或发票与相应的付款金额相连接,这样,付款金额的正数总和是尚未收取的金额,负数表示支付的款项(退还)。 order_id 6 怎么可能没有付款、发票金额或存储?它是未来购买的占位符吗?如果是这样,那可能很糟糕。