2016-06-16 203 views
0

我在mySQL有五張桌子,我正在學費模塊,但我在查詢中遇到一些問題,所以我無法得到適當的結果,所以請幫助我,如果您對我給予一些反饋,我將不勝感激此查詢。左外連接(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' 
+1

我剛剛格式化了您的代碼,以便您可以更輕鬆地閱讀它。告訴我,在最終查詢中是否有任何問題? –

+0

一個http://sqlfiddle.com/將在這裏幫助。 – Jocelyn

+0

@RichBenner是啊謝謝你。 –

回答

1

我看到您的查詢,你做了一點點失誤,在查詢中使用GROUP BY scholarAS lk後或查找AS lk和替換在查詢AS lk GROUP BY scholar ...!

+0

是啊,你已經仔細檢查過它......! –

4

複雜的查詢。不幸的是,錯誤。

首先,您可以從子查詢中刪除所有ORDER BY子句。子查詢只是返回無序集合,所以不論它們是否包含ORDER BY子句都沒有影響(除了給予DBMS不必要的工作外)。

最裏面的子查詢(kkk)沒有WHERE子句,也沒有GROUP BY子句,所以您可以直接從student_fee中直接選擇。

下一個子查詢(kk)組由scholarsection_id_fk組成,但您選擇due_amountfee_date而不進行任何聚合。這給你任意選擇的值。不應該是sum(due_amount)max(due_amount)或類似的?

然後在sssf子查詢中沒有GROUP BY子句。這給你一個結果行。但是,您選擇了未分類的scholar,section_id_fk,fee_date,stu_class,因此您可以再次獲得任意選擇的值,例如,所有的學者之一。

檢查所有聚合。這可能有助於設置ONLY_FULL_GROUP_BY模式,以避免錯誤。

+0

damm,打我吧+1 :) – Chris

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' 
+0

感謝您的努力,但在您的情況下,paid_amount顯示爲0,即使我已經插入一些金額的付費金額..看看上面的查詢正在工作......! –

2

檢查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' 
+0

大感謝@ghkhan,是的,它現在按照要求工作。我可以在這裏看到,我在這裏做了一個愚蠢的錯誤#group by scholar is the key ..謝謝的人 –

+0

歡迎:) – ghkhan