有结构:
CREATE TABLE `invoices` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `invoices` VALUES (1,'2018-09-22');
CREATE TABLE `products` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`invoice_id` int(10) unsigned NOT NULL,
`amount` decimal(10,2) unsigned NOT NULL,
`quantity` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `products` VALUES (1,1,150.00,2),(2,1,60.00,3),(3,1,50.00,1);
CREATE TABLE `payments` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`invoice_id` int(10) unsigned NOT NULL,
`amount` decimal(10,2) unsigned NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `payments` VALUES (1,1,400.00,'2018-09-23'),(2,1,80.00,'2018-09-23');
我有这个查询:
select i.id, sum(pr.amount * pr.quantity) as productAmount,
sum(pm.amount) as paymentAmount
from invoices as i
left join products as pr on pr.invoice_id=i.id
left join payments as pm on pm.invoice_id=i.id
group by i.id
并得到以下结果:
+----+---------------+---------------+
| id | productAmount | paymentAmount |
+----+---------------+---------------+
| 1 | 1060.00 | 1440.00 |
+----+---------------+---------------+
1 row in set (0,00 sec)
但是,我想得到以下结果:
+----+---------------+---------------+
| id | productAmount | paymentAmount |
+----+---------------+---------------+
| 1 | 530.00 | 480.00 |
+----+---------------+---------------+
1 row in set (0,00 sec)
我想要按invoice.id分组的产品总金额和付款总金额。
在这种情况下查询应该是什么?
答案 0 :(得分:2)
我有时会遇到这种查询。由于存在多个联接,因此特定表中的值将被重复,三重等。要解决此问题,我通常通过将总和(在特定表上)除以不同的Id( s)在 other 表中。这样可以消除重复发生的影响。
尝试以下查询:
select i.id,
(sum(pr.amount * pr.quantity) / IF(count(distinct pm.id) > 0, count(distinct pm.id), 1) as productAmount,
(sum(pm.amount) / IF(count(distinct pr.id) > 0, count(distinct pr.id), 1) as paymentAmount
from invoices as i
left join products as pr on pr.invoice_id=i.id
left join payments as pm on pm.invoice_id=i.id
group by i.id
答案 1 :(得分:2)
使用下面的子查询获取您期望的结果
SELECT id,
(select sum(pr.amount * pr.quantity) from products as pr where pr.invoice_id=i.id ) as productAmt,
(select sum(amount) from payments where invoice_id=i.id ) as PaymentAmt
FROM `invoices` i order by id asc
答案 2 :(得分:0)
尝试一下:https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=3b496214bf0ffb517dcaa9be7f0b6bb7
select a.id,pramount,sum(amount) as paymentamount from
(select i.id,sum(pr.amount *pr.quantity) as pramount
from invoices as i
join products as pr on pr.invoice_id=i.id
group by i.id)a
join payments pm on a.id=pm.invoice_id
group by a.id
答案 3 :(得分:0)
我可以想象这样的情况:创建发票但创建了产品却没有付款,类似地,创建发票却创建了付款但没有产品 。因此您可以为产品和付款创建子查询
drop table if exists i,pr,pm;
CREATE TABLE `i` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `i` VALUES (1,'2018-09-22'),(2,'2018-09-22'),(3,'2018-09-22'),(4,'2018-09-22');
CREATE TABLE `pr` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`invoice_id` int(10) unsigned NOT NULL,
`amount` decimal(10,2) unsigned NOT NULL,
`quantity` smallint(5) unsigned NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `pr` VALUES (1,1,150.00,2),(2,1,60.00,3),(3,1,50.00,1),(4,3,50.00,1);
CREATE TABLE `pm` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`invoice_id` int(10) unsigned NOT NULL,
`amount` decimal(10,2) unsigned NOT NULL,
`date` date NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB;
INSERT INTO `pm` VALUES (1,1,400.00,'2018-09-23'),(2,1,80.00,'2018-09-23'),(3,4,80.00,'2018-09-23');
select i.id, (select sum(pr.amount * pr.quantity) from pr where pr.invoice_id = i.id) as productAmount,
(select sum(pm.amount) from pm where pm.invoice_id = i.id) as paymentAmount
from i
having productAmount > 0 or paymentAmount > 0;
您可能(或可能不希望拥有Haven子句)
+----+---------------+---------------+
| id | productAmount | paymentAmount |
+----+---------------+---------------+
| 1 | 530.00 | 480.00 |
| 3 | 50.00 | NULL |
| 4 | NULL | 80.00 |
+----+---------------+---------------+
3 rows in set (0.00 sec)