显示不匹配的数据以及聚合函数和多个联接

时间:2017-02-02 20:06:25

标签: mysql sql join aggregate-functions

所以,我所拥有的是一个使用MySQL进行存储的系统,应该存储人们(捐赠者)的捐款。捐赠由授权用户输入系统。 以下是所有4个表的创建表:

CREATE TABLE `donator` (
 `DONATOR_ID` int(11) NOT NULL AUTO_INCREMENT,
 `DONATOR_NAME` varchar(50) NOT NULL,
 `STATUS` char(1) COLLATE NOT NULL DEFAULT 'A',
 PRIMARY KEY (`DONATOR_ID`)
) 

CREATE TABLE `user` (
 `USER_ID` int(11) NOT NULL AUTO_INCREMENT,
 `USERNAME` varchar(100) NOT NULL,
 `PASSWORD` varchar(200) NOT NULL,
 `TYPE` char(1) COLLATE NOT NULL,
 PRIMARY KEY (`USER_ID`)
)

CREATE TABLE `sif_res` (
 `RES_ID` int(11) NOT NULL AUTO_INCREMENT,
 `RES_NAME` varchar(50) NOT NULL,
 `MON_VAL` double NOT NULL,
 PRIMARY KEY (`RES_ID`)
)

CREATE TABLE `donations` (
 `DONATION_ID` int(11) NOT NULL AUTO_INCREMENT,
 `RESOURCE` int(11) NOT NULL,
 `AMOUNT` int(11) NOT NULL,
 `DONATOR` int(11) NOT NULL,
 `ENTRY_DATE` datetime NOT NULL,
 `ENTERED_BY_USER` int(11) NOT NULL,
 PRIMARY KEY (`DONATION_ID``),
 KEY `fk_resurs` (`RESOURCE``),
 KEY `fk_donator` (`DONATOR``),
 KEY `fk_user` (`ENTERED_BY_USER``),
 CONSTRAINT `fk_1` FOREIGN KEY (`DONATOR`) REFERENCES `donator` (`DONATOR_ID`) ON UPDATE CASCADE,
 CONSTRAINT `fk_2` FOREIGN KEY (`RESOURCE`) REFERENCES `sif_res` (`RES_ID`) ON UPDATE CASCADE,
 CONSTRAINT `fk_3` FOREIGN KEY (`ENTERED_BY_USER`) REFERENCES `user` (`USER_ID`) ON UPDATE CASCADE
) 

如您所见,我列出了可以捐赠的捐赠者,用户和资源。

现在,我想显示所有捐赠者的姓名和他们的身份证明,但是在第三栏中我想显示他们的余额(他们捐赠的所有项目的总和) - 这是用

计算的
  

donation.AMOUNT * sif_res.MON_VAL   每次捐赠

我编写的SQL SELECT有效,但没有捐赠任何内容的捐赠者被遗漏(他们没有被JOIN匹配)。我需要它显示每个人(使用STATUS!= D),即使他们没有任何条目(在这种情况下,他们的余额可能是0或NULL)

这是我写的SQL:

SELECT DONATOR_ID
, DONATOR_NAME
, round(SUM(d.AMOUNT * sr.MON_VAL)) as BALANCE 
from donator c 
join donations d on c.DONATOR_ID=d.DONATOR
join sif_res sr on sr.RES_ID=d.RESOURCE 
where c.STATUS!='D' 
group by DONATOR_ID, DONATOR_NAME

所以,如果我执行下一句话:

INSERT INTO donator(DONATOR_NAME, STATUS) VALUES("John", 'A'); //asigns id=1
INSERT INTO donator(DONATOR_NAME, STATUS) VALUES("Willie", 'A'); //asigns id=2

INSERT INTO user (USERNAME, PASSWORD, TYPE) VALUES("user", "pass", 'A'); //asigns id=1

INSERT INTO sif_res(RES_NAME, MON_VAL) VALUES("Flour", "0.5"); //asigns id=1

INSERT INTO donations(RESOURCE, AMOUNT, DONATOR, ENTRY_DATE, ENTERED_BY_USER) VALUES(1, 100, 1, '2.2.2017', 1);

我将得到输出(上面带有我的SELECT句子):

DONATOR_ID  |  DONATOR_NAME  |  BALANCE
--------------------------------------------
1           |  John          |  50  

我想得到的是:

DONATOR_ID  |  DONATOR_NAME  |  BALANCE
--------------------------------------------
1           |  John          |  50  
2           |  Willie        |  0

我已经尝试了所有版本的连接(左,右,外,全,...)但是它们都没有为我工作(可能是因为我使用它们错了)

如果仅仅是无法匹配的数据问题我就能解决它,但是聚合函数SUM和另一个JOIN使它变得更加复杂

1 个答案:

答案 0 :(得分:0)

在后两个表上使用左外连接应该可以解决问题:

SELECT c.DONATOR_ID
, c.DONATOR_NAME
, ifnull(round(SUM(d.AMOUNT * sr.MON_VAL)),0) as BALANCE 
from donator c 
left outer join donations d on c.DONATOR_ID=d.DONATOR
left outer join sif_res sr on sr.RES_ID=d.RESOURCE
where c.STATUS!='D' 
group by DONATOR_ID, DONATOR_NAME

我还将BALANCE表达式包装在ifnull中以显示0而不是null。