我正在尝试选择不在另一个表中的行。在这里,我已将 LEFT JOIN 与 IS NULL 结合使用,但没有得到预期的结果。它仅对一个表有效,而对另一个表无效。
主要是我无法管理四个表之间的关系。 fee
-包括费用类别)和fee_tm
-包括要支付费用的月份列表,cls_fee
-每个类别的费用标准)和invoice
-包含有关已付费用的信息费用)。
结果,我试图显示未付款的学生名单,或不在invoice
表中的那些学生记录。
Mysql
SELECT
fee_tm.id AS ftm_d,
fee.id AS f_id,
fee_tm.en_ttl AS f_tm,
fee.en_ttl AS fee,
cls_fee.fee AS f_mnt
FROM
fee
LEFT JOIN
fee_tm ON fee_tm.year = fee.year
LEFT JOIN
cls_fee ON cls_fee.fee_id = fee.id
LEFT JOIN
student ON student.cls = cls_fee.c_id AND student.sec = cls_fee.s_id
LEFT JOIN
invoice ON invoice.stu_id = student.id AND invoice.fee_id = fee.id AND invoice.ftm_id = fee_tm.id
WHERE
student.id =1 AND invoice.ftm_id is NULL AND invoice.fee_id is NULL
当前结果
ftm_d | f_id | f_tm | fee | f_mnt
=====================================================
2 | 1 | Feb | Annual | 1000
2 | 2 | Feb | Monthly | 560
预期结果
ftm_d | f_id | f_tm | fee | f_mnt
=====================================================
2 | 2 | Feb | Monthly | 560
我的结果仅检查f_tm
列,因此在我的当前结果月份Jan
被过滤,但它还必须检查fee
列和Annual
行必须被过滤。
因此,我们可以知道尚未支付学费的学生。如果在invoice
表中找到该记录,则应在结果中过滤此费用类别。
数据库结构
学生
id | en_ttl | cls | sec | year
========================================
1 | John | 1 | 1 | 1
cls
id | en_ttl | year
========================
1 | One | 1
秒
id | en_ttl | year
========================
1 | A | 1
费用
id | en_ttl | year
========================
1 | Annual | 1
2 | Monthly | 1
3 | Library | 1
fee_tm
id | en_ttl | year
========================
1 | Jan | 1
2 | Feb | 1
cls_fee
id | c_id | s_id | fee_id | fee
===============================================
1 | 1 | 1 | 1 | 1000
2 | 1 | 1 | 2 | 560
发票
id | stu_id | fee_id | ftm_id
======================================
1 | 1 | 1 | 1
表的DDL语句
CREATE TABLE `student` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`en_ttl` varchar(100) NOT NULL,
`cls` int(2) NOT NULL,
`sec` int(2) NOT NULL,
`year` int(1) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
CREATE TABLE `cls` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`en_ttl` varchar(50) NOT NULL,
`year` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
CREATE TABLE `sec` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`en_ttl` varchar(50) NOT NULL,
`year` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
CREATE TABLE `fee` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`en_ttl` varchar(50) NOT NULL,
`year` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
CREATE TABLE `fee_tm` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`en_ttl` varchar(50) NOT NULL,
`year` int(2) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
CREATE TABLE `cls_fee` (
`id` int(2) NOT NULL AUTO_INCREMENT,
`c_id` int(2) NOT NULL,
`s_id` int(2) NOT NULL,
`fee_id` int(2) NOT NULL,
`fee` int(6) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `fee` (`c_id`,`s_id`,`fee_id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=latin1;
CREATE TABLE `invoice` (
`id` int(4) NOT NULL AUTO_INCREMENT,
`stu_id` int(4) NOT NULL,
`fee_id` int(11) NOT NULL,
`ftm_id` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;
答案 0 :(得分:0)
在cluase中使用studentid = 1
SELECT
fee_tm.id AS ftm_d,
fee.id AS f_id,
fee_tm.en_ttl AS f_tm,
fee.en_ttl AS fee,
cls_fee.fee AS f_mnt
FROM
fee
inner JOIN
fee_tm ON fee_tm.year = fee.year and fee.id=fee_tm.id inner join cls_fee on cls_fee.fee_id = fee.id
LEFT JOIN
student ON student.cls = cls_fee.c_id AND student.sec = cls_fee.s_id
left join invoice ON invoice.stu_id = student.id AND invoice.fee_id = fee.id AND invoice.ftm_id = fee_tm.id and student.id=1
where invoice.fee_id is null