我在mySQL中有五个表,我正在研究学费模块,但我在查询时遇到了一些问题,所以我无法得到合适的结果所以请帮助我,如果你能给我一些反馈,我将不胜感激在此查询。
1.a)class_details表创建
CREATE TABLE `class_details`
(`class_id_pk` int(11) NOT NULL AUTO_INCREMENT
,`class_name`varchar(200) NOT NULL
,`session` varchar(50) DEFAULT NULL
,`class_status` varchar(50) DEFAULT NULL
,PRIMARY KEY (`class_id_pk`)
,UNIQUE KEY `UNIQUE` (`class_name`,`session`)) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
1.b)class_details插入
insert into `class_details`
(`class_id_pk`,`class_name`,`session`,`class_status`)
VALUES
(1,'1st','2016-2017',NULL)
,(2,'2nd','2016-2017',NULL)
,(3,'3rd','2016-2017',NULL);
2.a)feedetails表创建
CREATE TABLE `feedetails`
(`section_id_fk` int(50) NOT NULL
,`fees` varchar(30) DEFAULT NULL
,PRIMARY KEY (`section_id_fk`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
2.b)feedetails插入
insert into `feedetails`(`section_id_fk`,`fees`)
values
(1,'1000')
,(2,'2000')
,(3,'3000')
,(4,'4000')
,(5,'5000')
,(6,'6000');
3.a)section_details创建
CREATE TABLE `section_details`
(`section_id_pk` int(11) NOT NULL AUTO_INCREMENT
,`class_id_fk` int(11) NOT NULL
,`section_name` varchar(50) NOT NULL
,`section_status` varchar(50) DEFAULT NULL
,PRIMARY KEY (`section_id_pk`,`class_id_fk`,`section_name`)
,UNIQUE KEY `UNIQUE` (`class_id_fk`,`section_name`)
,CONSTRAINT `FK_section_details` FOREIGN KEY (`class_id_fk`) REFERENCES `class_details` (`class_id_pk`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=latin1;
3.b)section_details插入
insert into `section_details` (`section_id_pk`,`class_id_fk`,`section_name`,`section_status`)
values
(1,1,'A',NULL)
,(2,2,'A',NULL)
,(3,3,'A',NULL);
4.a)student_fee
CREATE TABLE `student_fee`
( `sr_no` int(200) NOT NULL AUTO_INCREMENT
,`scholar_no`int(50) NOT NULL
,`paid_amount` int(200) DEFAULT NULL
,`due_amount` int(200) DEFAULT NULL
,`fee_date` date DEFAULT NULL
,`section_id_fk` int(50) DEFAULT NULL
,PRIMARY KEY (`sr_no`)
,KEY `FK_student_fee`(`section_id_fk`)
,CONSTRAINT `FK_student_fee` FOREIGN KEY (`section_id_fk`) REFERENCES `section_details` (`section_id_pk`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1;
4.b)student_fee插入
insert into student_fee` (`sr_no`,`scholar_no`,`paid_amount`,`due_amount`,`fee_date`,`section_id_fk`)
values
(3,5,800,200,'2016-06-16',1)
,(4,29,1000,0,'2016-06-16',1)
,(5,5,200,0,'2016-06-16',1);
5.a)student_details创建
CREATE TABLE `student_details`
(`scholar_no` int(30) NOT NULL
,`fname` varchar(30) DEFAULT NULL
,`lname` varchar(30) DEFAULT NULL
,`stu_class` varchar(30) DEFAULT NULL
,`rte` varchar(30) DEFAULT NULL
,`active` varbinary(10) DEFAULT NULL
,PRIMARY KEY (`scholar_no`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;
5.b)student_details插入
insert into `student_details` (`scholar_no`,`fname`,`lname`,`stu_class`,`rte`,`active`)
values
(5,'KP','PK','1','N','y')
,(29,'Abc','Xyz','1','N','y');
上面我提到了用于此查询的所有表详细信息。 第一次在student_details表中stu_class = 1并且费用将是1000.当我在student_fee中插入一些值并使用我的查询然后结果是正确的但是当我在student_fee中插入一些金额给另一个学生时,查询添加了付费金额对于那个不正确的同一个学生,我想显示实际插入的学生的插入费用..
SELECT
student_details.scholar_no
,student_details.fname
,student_details.lname
,student_details.stu_class
,feedetails.fees
,class_name
,section_name
,IF(sssf.paid_amount IS NULL,0,sssf.paid_amount) AS paid_amount
FROM
(student_details
LEFT OUTER JOIN feedetails
ON student_details.stu_class = feedetails.section_id_fk
)
LEFT OUTER JOIN
(SELECT
scholar
, SUM(pa) AS paid_amount
, SUM(pva) AS prev_paid_amount
,SUM(da) AS due_amount
, SUM(dva) AS prev_due_amount
,section_id_fk
,fee_date
,stu_class
FROM
(SELECT
scholar
,CASE WHEN section_id_fk = stu_class THEN paid_amount ELSE 0 END AS pa
,CASE WHEN section_id_fk != stu_class THEN paid_amount ELSE 0 END AS pva
,CASE WHEN section_id_fk = stu_class THEN due_amount ELSE 0 END AS da
,CASE WHEN section_id_fk != stu_class THEN due_amount ELSE 0 END AS dva
,due_amount
,paid_amount
,section_id_fk
,fee_date
,stu_class
FROM
(SELECT
scholar
,due_amount
,SUM(paid_amount) AS paid_amount
,section_id_fk
,fee_date
FROM
(SELECT
student_fee.due_amount AS due_amount
,student_fee.paid_amount AS paid_amount
,student_fee.scholar_no AS scholar
,section_id_fk
,fee_date
FROM student_fee
ORDER BY STR_TO_DATE(fee_date,'%Y-%m-%d')DESC
) AS kkk
GROUP BY kkk.scholar,section_id_fk ORDER BY scholar
) AS k
LEFT OUTER JOIN student_details sd
ON k.scholar = sd.scholar_no
) AS lk
) AS sssf
ON student_details.scholar_no = sssf.scholar
LEFT OUTER JOIN
(SELECT *
FROM section_details AS sd
LEFT OUTER JOIN class_details cd
ON sd.class_id_fk = cd.class_id_pk
) AS sc
ON student_details.stu_class = sc.section_id_pk
WHERE student_details.active = 'y' AND rte = 'N'
答案 0 :(得分:4)
复杂的查询。然而不幸的是。
首先,您可以从子查询中删除所有ORDER BY
子句。子查询只返回无序集,因此它们是否包含ORDER BY
子句无效(除了给DBMS不必要的工作之外)。
最里面的子查询(kkk)没有WHERE
子句,没有GROUP BY
子句,所以你也可以直接从student_fee
中选择。
下一个子查询(kk)按scholar
和section_id_fk
分组,但您选择due_amount
和fee_date
而不进行任何聚合。这为您提供了任意选择的值。那不应该是sum(due_amount)
或max(due_amount)
之类的吗?
然后在sssf子查询中没有GROUP BY
子句。这为您提供了一个结果行。但是,您选择了未加密的scholar
,section_id_fk
,fee_date
,stu_class
,因此您可以再次获得任意选择的值,例如所有学者中的一个。
检查所有汇总。设置ONLY_FULL_GROUP_BY
模式可能有所帮助,以避免错误。
答案 1 :(得分:1)
检查下面的SQL,我有一个快速修复。如果不解决,请多解释一下你的问题。
SELECT
student_details.scholar_no
,student_details.fname
,student_details.lname
,student_details.stu_class
,feedetails.fees
,class_name
,section_name
,IF(sssf.paid_amount IS NULL,0,sssf.paid_amount) AS paid_amount
FROM
(student_details
LEFT OUTER JOIN feedetails
ON student_details.stu_class = feedetails.section_id_fk
)
LEFT OUTER JOIN
(SELECT
scholar
, SUM(pa) AS paid_amount
, SUM(pva) AS prev_paid_amount
,SUM(da) AS due_amount
, SUM(dva) AS prev_due_amount
,section_id_fk
,fee_date
,stu_class
FROM
(SELECT
scholar
,CASE WHEN section_id_fk = stu_class THEN paid_amount ELSE 0 END AS pa
,CASE WHEN section_id_fk != stu_class THEN paid_amount ELSE 0 END AS pva
,CASE WHEN section_id_fk = stu_class THEN due_amount ELSE 0 END AS da
,CASE WHEN section_id_fk != stu_class THEN due_amount ELSE 0 END AS dva
,due_amount
,paid_amount
,section_id_fk
,fee_date
,stu_class
FROM
(SELECT
scholar
,due_amount
,SUM(paid_amount) AS paid_amount
,section_id_fk
,fee_date
FROM
(SELECT
student_fee.due_amount AS due_amount
,student_fee.paid_amount AS paid_amount
,student_fee.scholar_no AS scholar
,section_id_fk
,fee_date
FROM student_fee
ORDER BY STR_TO_DATE(fee_date,'%Y-%m-%d')DESC
) AS kkk
GROUP BY kkk.scholar,section_id_fk ORDER BY scholar
) AS k
LEFT OUTER JOIN student_details sd
ON k.scholar = sd.scholar_no
) AS lk
group by scholar
) AS sssf
ON student_details.scholar_no = sssf.scholar
LEFT OUTER JOIN
(SELECT *
FROM section_details AS sd
LEFT OUTER JOIN class_details cd
ON sd.class_id_fk = cd.class_id_pk
) AS sc
ON student_details.stu_class = sc.section_id_pk
WHERE student_details.active = 'y' AND rte = 'N'
答案 2 :(得分:0)
试试这个
SELECT
student_details.scholar_no
,student_details.fname
,student_details.lname
,student_details.stu_class
,feedetails.fees
,class_name
,section_name
,IF(sssf.paid_amount IS NULL,0,sssf.paid_amount) AS paid_amount
FROM
(student_details
LEFT OUTER JOIN feedetails
ON student_details.stu_class = feedetails.section_id_fk
)
LEFT OUTER JOIN
(SELECT
scholar
,pa AS paid_amount
,pva AS prev_paid_amount
,da AS due_amount
,dva AS prev_due_amount
,section_id_fk
,fee_date
,stu_class
FROM
(SELECT
scholar
,CASE WHEN section_id_fk = stu_class THEN paid_amount ELSE 0 END AS pa
,CASE WHEN section_id_fk != stu_class THEN paid_amount ELSE 0 END AS pva
,CASE WHEN section_id_fk = stu_class THEN due_amount ELSE 0 END AS da
,CASE WHEN section_id_fk != stu_class THEN due_amount ELSE 0 END AS dva
,due_amount
,paid_amount
,section_id_fk
,fee_date
,stu_class
FROM
(SELECT
scholar
,due_amount
,paid_amount AS paid_amount
,section_id_fk
,fee_date
FROM
(SELECT
student_fee.due_amount AS due_amount,SUM(student_fee.paid_amount) AS paid_amount,student_fee.scholar_no AS scholar,section_id_fk,fee_date
FROM student_fee GROUP BY scholar
ORDER BY STR_TO_DATE(fee_date,'%Y-%m-%d')DESC
) AS kkk
ORDER BY scholar
) AS k
LEFT OUTER JOIN student_details sd
ON k.scholar = sd.scholar_no
) AS lk
) AS sssf
ON student_details.scholar_no = sssf.scholar
LEFT OUTER JOIN
(SELECT *
FROM section_details AS sd
LEFT OUTER JOIN class_details cd
ON sd.class_id_fk = cd.class_id_pk
) AS sc
ON student_details.stu_class = sc.section_id_pk
WHERE student_details.active = 'y' AND rte = 'N'
答案 3 :(得分:0)
我看到了您的查询并且您犯了一点错误,在查询中GROUP BY scholar
之后使用AS lk
或在查询中查找AS lk
并替换AS lk GROUP BY scholar
。 !