SQL Multiple foreign keys referring to the same table - sql

I have the following table Student:
Id FirstName LastName State Index Year Course1 Course2 Course3 Course4 Course5
622 Student622 LastName622 State17 62200 2 54 47 68 67 50
623 Student623 LastName623 State16 62300 3 17 99 37 99 32
624 Student624 LastName624 State2 62400 4 8 71 11 58 86
625 Student625 LastName625 State1 62500 2 39 75 33 77 17
626 Student626 LastName626 State15 62600 3 11 3 4 70 72
627 Student627 LastName627 State13 62700 2 84 77 65 62 76
628 Student628 LastName628 State13 62800 4 87 18 19 4 75
629 Student629 LastName629 State10 62900 2 96 67 14 97 31
The numbers in Course 1, 2, 3, 4, 5 are foreign key values that refer to the id of the following Courses table:
Id Name ProfessorId
1 Course 1 8
2 Course 2 14
3 Course 3 4
4 Course 4 3
5 Course 5 6
6 Course 6 2
7 Course 7 14
8 Course 8 4
9 Course 9 5
How can write script so that when i execute instead of foreign key numbers there is the Course name? Any thoughts?

You could LEFT JOIN to the Course table for each course id.
SELECT
s.Id, s.FirstName, s.LastName, s.State, s.[Index], s.[Year],
c1.Name as Course1Name,
c2.Name as Course2Name,
c3.Name as Course3Name,
c4.Name as Course4Name,
c5.Name as Course5Name
FROM Student s
LEFT JOIN Courses c1 ON c1.Id = s.Course1
LEFT JOIN Courses c2 ON c2.Id = s.Course2
LEFT JOIN Courses c3 ON c3.Id = s.Course3
LEFT JOIN Courses c4 ON c4.Id = s.Course4
LEFT JOIN Courses c5 ON c5.Id = s.Course5
Because those are all LEFT JOIN's, all the records of Student will be returned.
Even if some course id's aren't filled in.

Related

PostgreSQL: Return entries based on conditions and grouping

Imagine the following table:
result_id student subject grade
1 Anne A 63
2 Anne B 63
3 Bob A 89
4 Bob B 51
5 Carla A 70
6 Carla B 70
7 Carla C 68
8 Dylan B 75
9 Dylan C 54
I would like to return the entries where a student got the exact same grade for subject A and B. So the ideal output would be:
result_id student subject grade
1 Anne A 63
2 Anne B 63
5 Carla A 70
6 Carla B 70
Can this even be achieved with queries? Struggling to find information about it.
A bit complicated but I hope easy to read.
select * from the_table
where student in
(
with t as
(
select student, count(*) cnt, min(grade) mig, max(grade) mag
from the_table
where subject in ('A', 'B') group by student
)
select student from t where mig = mag and cnt = 2
)
and subject in ('A', 'B')
order by student, subject;
result_id
student
subject
grade
1
Anne
A
63
2
Anne
B
63
5
Carla
A
70
6
Carla
B
70

SQL LOGIC using 3conditions

course_completions CC
id coursemodid userid state timemodified
370 23 2 1 1433582890
329 24 89 1 1427771915
333 30 39 1 1428309816
332 32 39 1 1428303307
327 33 40 1 1427689703
328 34 89 1 1427710711
303 35 41 1 1410258482
358 36 99 1 1432020067
365 25 2 1 1433142455
304 26 69 1 1410717866
353 37 95 1 1430387005
416 38 2 1 1438972465
300 27 70 1 1409824001
302 29 74 1 1412055704
297 30 2 1 1409582123
301 133 41 1 1410255923
336 133 91 1 1428398435
364 133 40 1 1433142348
312 133 85 1 1425863621
course_modules CM
id course
23 6
24 6
25 6
26 6
27 6
28 6
29 8
30 8
31 8
32 8
33 8
34 5
35 5
36 5
37 5
38 5
39 9
40 9
41 9
course_mod_settings CMS
id course modinstance
27 8 30
28 8 31
29 8 32
30 8 33
31 6 23
32 6 24
33 6 25
34 6 26
35 6 27
36 6 28
37 9 39
38 9 40
39 9 41
I need the count of each user has Completed modules, Inprocess modules and Notstarted modules for each course, where getting the count of userids from table CC by taking courseia from table CM, get number of modules that an user has completed from each course.
(A course can have morethan one module and a course can have number of users attempted all modules, few modules or not attempted at all).
So, I need number of users - has done number of modules - in a course. (3 logics)
Completed.Users means : If number of modules attempted is equal to number of modinstance from table CMS (ex: no. of modules attempted by a user per course= 9, no.modinstance = 9. Because 7 is not equal to 9, They are completed.)
Inprocess.Users means : Number of modules attempted should be >0, but not equal to [count(modinstance) per course] (ex: no. of modules attempted by a user per course= 7 , no.modinstance = 9. Because 7 is not equal to 9, They are Inprocess.)
Notstarted.Users means : Number of modules attempted should be equal to 0, (ex: no. of modules attempted by a user per course= 0. They are Notstarted).
OUTPUT :
Course No.Completed.Users No.Inprocess.Users No.Notstarted.Users
5 65 32 6
6 40 12 15
8 43 56 0
9 0 7 9
Sir, this is a very critical logic that I was trying, I couldn't get a solution. I hope stackoverflow developers could help me out. I tried with my query :
SELECT cm.course AS "Course",
(CASE WHEN
(SELECT count(cms.id) FROM course_mod_settings cms) =
(SELECT count(cmc.coursemodid) FROM course_completions cc JOIN course_modules cm ON cmc.coursemodid = cm.id WHERE cmc.state=1 )
THEN COUNT(SELECT count(cmc.coursemodid) FROM course_completions cc JOIN course_modules cm ON cmc.coursemodid = cm.id WHERE cmc.state=1 ) END) AS "No.Completed.Users",
(CASE WHEN
(SELECT count(cms.id) FROM course_mod_settings cms) > 0 AND
(SELECT count(cms.id) FROM course_mod_settings cms) !=
(SELECT count(cmc.coursemodid) FROM course_completions cc JOIN course_modules cm ON cmc.coursemodid = cm.id WHERE cmc.state=1 )
THEN COUNT(SELECT count(cmc.coursemodid) FROM course_completions cc JOIN course_modules cm ON cmc.coursemodid = cm.id WHERE cmc.state=1 ) END) AS "No.Inprocess.Users",
(CASE WHEN
(SELECT count(cms.id) FROM course_mod_settings cms) = 0
THEN COUNT(SELECT count(cmc.coursemodid) FROM course_completions cc JOIN course_modules cm ON cmc.coursemodid = cm.id WHERE cmc.state=1 ) END) AS "No.Notstarted.Users"
FROM
mdl_course c
GROUP BY c.id
SQL Fiddle
SELECT course AS "Course",
SUM(CASE WHEN completion_count = module_count THEN 1 ELSE 0 END) AS "No.Completed.Users",
SUM(CASE WHEN completion_count > 0 AND completion_count < module_count THEN 1 ELSE 0 END) AS "No.Inprocess.Users",
SUM(CASE WHEN completion_count = 0 THEN 1 ELSE 0 END) AS "No.Notstarted.Users"
FROM (SELECT course, COUNT(*) AS module_count
FROM course_modules cm
GROUP BY course) course_module_counts JOIN
(SELECT cm.course AS courseid, users.id AS userid, SUM(CASE WHEN cc.state = 1 THEN 1 ELSE 0 END) completion_count
FROM ((SELECT DISTINCT userid AS id FROM course_completions) users CROSS JOIN course_modules cm) LEFT JOIN course_completions cc ON users.id = cc.userid AND cc.coursemodid = cm.id
GROUP BY cm.course, users.id) course_completion_counts
ON course_module_counts.course = course_completion_counts.courseid
GROUP BY course
gives this output, which matches the limited dataset that you provided in your question.
| course | No.Completed.Users | No.Inprocess.Users | No.Notstarted.Users |
|--------|--------------------|--------------------|---------------------|
| 5 | 0 | 5 | 7 |
| 6 | 0 | 4 | 8 |
| 8 | 0 | 4 | 8 |
| 9 | 0 | 0 | 12 |

Oracle query performance issue?

How to tune the below query?
SELECT /* + ALL_ROWS */
distinct
--(select name from team where team_id in (select team_id from alignment where alignment_id=a.alignment_id))as team_name,
(select name from team where team_id=a.team_id) as team_name,
e.employee_id, --REP EMPLOYEE_ID
c.external_id_2,
c.name || ','|| c.first_name as customer_name,
c.customer_sub_type, -- spcialty
event.ENTRY_DATE ,
CASE
WHEN event.EVENT_TYPE='C' and event.APPOINTMENT_TYPE='GA' THEN 'Via Appointment'
WHEN event.EVENT_TYPE='C' and event.APPOINTMENT_TYPE is null THEN 'Direct Call'
ELSE '-'
END EVENT_TYPE,
event.Event_id,
rating.rating_category, -- RATING CATEGORY
rating.call_frequency,
adr.line_1_address address1, -- address1
adr.line_2_address address2, --address2
adr.city, --city
adr.state, --state
adr.geography_code_1, -- brick name
event.start_date_time, --Start date
event.status_change_date,
nt.note_text call_objective,--next call OBJECTIVE
ed.text_1 as Call_Objective_results,
(select display_name from product where product_id in(select max(product_id) from event_detail where sequence=1 and event_id=event.event_id)) as product_1,
(select display_name from product where product_id in(select max(product_id) from event_detail where sequence=2 and event_id=event.event_id)) as product_2,
(select display_name from product where product_id in(select max(product_id) from event_detail where sequence=3 and event_id=event.event_id)) as product_3,
(select display_name from product where product_id in (
(select max(product_id) from event_item where product_id in (ei.product_id) ))) || ' , '|| ei.quantity as promotinal_items_type_quantity,
(select display_name from product where product_id in (
(select max(product_id) from sample_transaction where product_id not in (ei.product_id) and event_id=event.event_id)))|| ' , '||
(select physical_quantity from sample_transaction where product_id in (
(select max(product_id) from product where product_id not in (ei.product_id) and event_id=event.event_id)) ) as pob_product_quantity,
event.accompanied_by,
--(select ACCOMPANIED_BY from event ev where tenant_id=500020 and employee_id in (::employee_id) and ev.event_id=event.event_id) Accompanied_BY,
event.status,
event.end_date_time FROM employee e
inner join alignment a on e.employee_id=a.employee_id
inner join
(
select event_id,alignment_id,employee_id,affiliation_id,customer_id, interaction_channel, start_date_time,end_date_time,STATUS_CHANGE_DATE,
ENTRY_DATE ,EVENT_TYPE,APPOINTMENT_TYPE,
status,accompanied_by from event ev where
ev.event_type in (::event_type) and tenant_id=500020 and start_date_time>=:start_date AND end_date_time<=:end_date and
ev.employee_id in
(
select employee_id from alignment where manager_alignment_id in
(
select alignment_id from alignment where manager_alignment_id in
(
select alignment_id from alignment where employee_id in
(
::employee_id
)
)
) or manager_alignment_id in(
select alignment_id from alignment where employee_id in
(
::employee_id
)
)
or alignment_id in(
select alignment_id from alignment where employee_id in
(
::employee_id
)
)
) and ev.status in (::status) or (ev.tenant_id=500020 and 'VPOS'=(select distinct role from alignment where employee_id in ( ::employee_id ) AND role='VPOS' ) and ev.event_type in (::event_type) and start_date_time>=:start_date AND end_date_time<=:end_date)
)event on a.employee_id=event.employee_id and event.interaction_channel ='INPR'
inner join affiliation aff on event.affiliation_id=aff.affiliation_id
left outer join event_dynamic ed on event.event_id=ed.event_id
left outer join event_item ei on ei.event_id=event.event_id
inner join customer c on c.customer_id=event.customer_id and c.customer_type IN ('PRES','NPRS')
left outer join address adr on aff.address_id=adr.address_id
left outer join notes nt on event.event_id=nt.event_id and nt.customer_id=c.customer_id and note_type='CC'
left outer join
(
select dnr.dn_rating_attribute_id,r.team_id,
r.customer_id,
(select note_text from notes where
CUSTOMER_ID=r.customer_id
and note_type='CC' and event_id IS null) nextcall_objective,
r.user_account_id,
r.value_min,
case
when r.value_min = '1' then 'A'
when r.value_min= '2' then 'B'
when r.value_min = '3' then 'C'
end RATING_CATEGORY
from dn_rating_attribute dnr
inner join rating r on r.dn_rating_attribute_id=dnr.dn_rating_attribute_id
where dnr.external_id_1='IND_CATEGORY'
) rating on c.customer_id=rating.customer_id and rating.team_id in ( select team_id from alignment where employee_id=event.employee_id )
left outer join
(
select dnr.dn_rating_attribute_id,r.team_id,
r.customer_id,
r.user_account_id,
r.value_min,
case
when r.value_min = '1' then '1'
when r.value_min= '2' then '2'
when r.value_min = '3' then '3'
end Call_frequency
from dn_rating_attribute dnr
inner join rating r on r.dn_rating_attribute_id=dnr.dn_rating_attribute_id
where dnr.external_id_1='IND_CALLFREQUENCY'
) rating on c.customer_id=rating.customer_id and rating.team_id in ( select team_id from alignment where employee_id=event.employee_id )
It is taking long time to fetch the records. I am not sure where it is taking long time. Shall I use any hints for this.
Here is the Execution Plan
0 SELECT STATEMENT 36114 11M 503880 12G 503424
1 0 INDEX RANGE SCAN PEUSPMMI.TEAM_PF1 1 19 1 7321 1
2 0 TABLE ACCESS BY INDEX ROWID PEUSPMMI.PRODUCT 1 25 2 15463 2
3 2 INDEX UNIQUE SCAN PEUSPMMI.PRODUCT_PK 1 1 8171 1
4 3 SORT AGGREGATE 1 21
5 4 TABLE ACCESS BY INDEX ROWID PEUSPMMI.EVENT_DETAIL 1 21 4 29817 4
6 5 INDEX RANGE SCAN PEUSPMMI.EVENT_DETAIL_PF2 2 3 21964 3
7 0 TABLE ACCESS BY INDEX ROWID PEUSPMMI.PRODUCT 1 25 2 15463 2
8 7 INDEX UNIQUE SCAN PEUSPMMI.PRODUCT_PK 1 1 8171 1
9 8 SORT AGGREGATE 1 21
10 9 TABLE ACCESS BY INDEX ROWID PEUSPMMI.EVENT_DETAIL 1 21 4 29817 4
11 10 INDEX RANGE SCAN PEUSPMMI.EVENT_DETAIL_PF2 2 3 21964 3
12 0 TABLE ACCESS BY INDEX ROWID PEUSPMMI.PRODUCT 1 25 2 15463 2
13 12 INDEX UNIQUE SCAN PEUSPMMI.PRODUCT_PK 1 1 8171 1
14 13 SORT AGGREGATE 1 21
15 14 TABLE ACCESS BY INDEX ROWID PEUSPMMI.EVENT_DETAIL 1 21 4 29817 4
16 15 INDEX RANGE SCAN PEUSPMMI.EVENT_DETAIL_PF2 2 3 21964 3
17 0 TABLE ACCESS BY INDEX ROWID PEUSPMMI.PRODUCT 1 25 2 15463 2
18 17 INDEX UNIQUE SCAN PEUSPMMI.PRODUCT_PK 1 1 8171 1
19 18 SORT AGGREGATE 1 10
20 19 FIRST ROW 68 680 1 21571 1
21 20 INDEX RANGE SCAN (MIN/MAX) PEUSPMMI.EVENT_ITEM_FK2 68 680 1 21571 1
22 0 TABLE ACCESS BY INDEX ROWID PEUSPMMI.PRODUCT 1 25 2 15463 2
23 22 INDEX UNIQUE SCAN PEUSPMMI.PRODUCT_PK 1 1 8171 1
24 23 SORT AGGREGATE 1 19
25 24 TABLE ACCESS BY INDEX ROWID PEUSPMMI.SAMPLE_TRANSACTION 1 19 2 15974 2
26 25 INDEX RANGE SCAN PEUSPMMI.SAMPLE_TRANSACTION_FK4 1 1 8371 1
27 0 FILTER
28 27 TABLE ACCESS FULL PEUSPMMI.SAMPLE_TRANSACTION 37771 848K 205 18M 204
29 27 SORT AGGREGATE 1 9
30 29 FILTER
31 30 FIRST ROW 1 9 2 14493 2
32 31 INDEX FULL SCAN (MIN/MAX) PEUSPMMI.PRODUCT_PK 1 9 2 14493 2
33 0 HASH UNIQUE 36114 11M 503880 12G 503424 11M
34 33 NESTED LOOPS OUTER 36114 11M 501364 12G 500912
35 34 NESTED LOOPS OUTER 36114 10M 284619 11G 284228
36 35 HASH JOIN OUTER 36114 10M 67875 9G 67544 8576K
37 36 VIEW 36114 8146K 53266 8G 52971
38 37 FILTER
39 38 HASH JOIN RIGHT OUTER 36114 10M 53263 8G 52969
40 39 TABLE ACCESS FULL PEUSPMMI.EVENT_ITEM 7860 168K 17 2692444 17
41 39 NESTED LOOPS 36114 10M 53246 8G 52952
42 41 HASH JOIN 36114 9980K 53243 8G 52952
43 42 TABLE ACCESS FULL PEUSPMMI.ALIGNMENT 950 16K 10 816335 10
44 42 HASH JOIN OUTER 36114 9345K 53233 8G 52942 8504K
45 44 HASH JOIN OUTER 35521 8082K 45773 7G 45525 5920K
46 45 HASH JOIN 35445 5503K 41799 6G 41569 3992K
47 46 HASH JOIN 35484 3569K 30983 4G 30814 3368K
48 47 TABLE ACCESS FULL PEUSPMMI.EVENT 35530 2949K 27495 4G 27343
49 47 INDEX FAST FULL SCAN PEUSPMMI.AFFILIATION_PF12 1342K 23M 1412 195M 1405
50 46 TABLE ACCESS FULL PEUSPMMI.CUSTOMER 706K 37M 8346 1G 8292
51 45 TABLE ACCESS FULL PEUSPMMI.ADDRESS 303K 21M 2449 431M 2434
52 44 TABLE ACCESS FULL PEUSPMMI.EVENT_DYNAMIC 1255K 38M 4426 906M 4394
53 41 INDEX UNIQUE SCAN PEUSPMMI.EMPLOYEE_PK 1 9 0 1900 0
54 38 FILTER
55 54 TABLE ACCESS BY INDEX ROWID PEUSPMMI.ALIGNMENT 1 23 2 15640 2
56 55 INDEX UNIQUE SCAN PEUSPMMI.ALIGNMENT_UK1 1 1 8171 1
57 54 NESTED LOOPS
58 57 NESTED LOOPS 1 31 3 23674 3
59 58 INDEX RANGE SCAN PEUSPMMI.ALIGNMENT_PF2 1 15 2 14463 2
60 58 INDEX UNIQUE SCAN PEUSPMMI.ALIGNMENT_UK1 1 0 1900 0
61 57 TABLE ACCESS BY INDEX ROWID PEUSPMMI.ALIGNMENT 1 16 1 9211 1
62 54 TABLE ACCESS BY INDEX ROWID PEUSPMMI.ALIGNMENT 1 16 2 15533 2
63 62 INDEX UNIQUE SCAN PEUSPMMI.ALIGNMENT_UK1 1 1 8171 1
64 54 TABLE ACCESS BY INDEX ROWID PEUSPMMI.ALIGNMENT 1 16 2 15533 2
65 64 INDEX UNIQUE SCAN PEUSPMMI.ALIGNMENT_UK1 1 1 8171 1
66 38 TABLE ACCESS BY INDEX ROWID PEUSPMMI.ALIGNMENT 1 12 2 15693 2
67 66 INDEX UNIQUE SCAN PEUSPMMI.ALIGNMENT_UK1 1 1 8171 1
68 36 TABLE ACCESS FULL PEUSPMMI.NOTES 1138K 89M 9125 700M 9100
69 35 VIEW 1 6 6 47959 6
70 69 NESTED LOOPS
71 70 NESTED LOOPS 1 75 6 47959 6
72 71 MERGE JOIN CARTESIAN 1 52 3 25134 3
73 72 TABLE ACCESS BY INDEX ROWID PEUSPMMI.DN_RATING_ATTRIBUTE 1 34 2 15903 2
74 73 INDEX RANGE SCAN PEUSPMMI.DN_RATING_ATTRIBUTE_PF2 1 1 8171 1
75 72 BUFFER SORT 1 18 1 9231 1
76 75 TABLE ACCESS BY INDEX ROWID PEUSPMMI.ALIGNMENT 1 18 1 9231 1
77 76 INDEX UNIQUE SCAN PEUSPMMI.ALIGNMENT_UK1 1 0 1900 0
78 71 INDEX RANGE SCAN PEUSPMMI.RATING_UK1 1 2 15313 2
79 70 TABLE ACCESS BY INDEX ROWID PEUSPMMI.RATING 1 23 3 22824 3
80 34 VIEW 1 6 6 47959 6
81 80 NESTED LOOPS
82 81 NESTED LOOPS 1 75 6 47959 6
83 82 MERGE JOIN CARTESIAN 1 52 3 25134 3
84 83 TABLE ACCESS BY INDEX ROWID PEUSPMMI.DN_RATING_ATTRIBUTE 1 34 2 15903 2
85 84 INDEX RANGE SCAN PEUSPMMI.DN_RATING_ATTRIBUTE_PF2 1 1 8171 1
86 83 BUFFER SORT 1 18 1 9231 1
87 86 TABLE ACCESS BY INDEX ROWID PEUSPMMI.ALIGNMENT 1 18 1 9231 1
88 87 INDEX UNIQUE SCAN PEUSPMMI.ALIGNMENT_UK1 1 0 1900 0
89 82 INDEX RANGE SCAN PEUSPMMI.RATING_UK1 1 2 15313 2
90 81 TABLE ACCESS BY INDEX ROWID PEUSPMMI.RATING 1 23 3 22824 3
Please do the needful.
I am using Oracle 11g.
"I am not sure where it is taking long time."
There's no need to guess. Use Real-Time SQL Monitoring to find out exactly which operations are running the longest. (If you continue to use the package it may require additional licensing, but you should at least evaluate it.)
select dbms_sqltune.report_sql_monitor(sql_id => 'your_id', type => 'text') from dual;
There are a few other ways to do this such as tracing, GATHER_PLAN_STATISTICS hint, etc. But SQL Monitoring is the easiest to use and provides the most information. Explain plans alone are usually not enough to tune large SQL statements with complex execution plans.
Edit your question with the results and the root cause may be obvious to spot.

adding columns to get total and ranking total

this my table
student_numbers
ROLL_NO NAME CLASS HINDI MATHS SCIENCE
2 amit 11 91 91 81
3 anirudh 11 88 87 81
4 akash 11 82 81 85
5 pratik 10 81 99 98
7 rekha 10 79 97 82
6 neha 10 89 91 90
8 kamal 10 66 68 69
1 ankit 11 97 98 87
i want to add last three columns and rank on that total partitioned by class
this is what i tried
select roll_no,name,class,total,
rank() over (partition by class order by total desc) as rank
from student_numbers,(select hindi+maths+science total from student_numbers)
;
but this is showing a very large table,with duplicate student name having different total .
I'm not exactly sure what you are trying to accomplish -- order the highest grades by class? If so, something like this should work:
SELECT SN.Roll_No,
SN.Class,
SN2.Total,
RANK() OVER (PARTITION BY SN.Class ORDER BY SN2.Total DESC) as rank
FROM Student_Numbers SN
JOIN (
SELECT
Roll_no, hindi+maths+science as Total
FROM Student_Numbers
) SN2 ON SN.Roll_No = SN2.Roll_No
Here is the SQL Fiddle.
Good luck.

sum of two field in two table

I have four tables in the database as follows:
tblInvoice:
invcid,customerid,invoicedate
tblInvcDetail:
ID,invcid,item,itemprice,itemquantity
tblPay:
payid,invcid,paydate
tblPayDetail:
payid,amount
I need to create a list of invoiceid, invoicedate, (sum of itemprice*itemquantity), (sum of amount) where userid is given.
I tried this query:
SELECT tblinvoice.invcid,
tblinvoice.invcdate,
Sum(tblinvcdetail.itemprice * tblinvcdetail.itemquantity) AS SumOfInvoice,
Sum(tblpaydetail.amount) AS SumOfAmount
FROM ((tblinvoice
LEFT JOIN tblpay
ON tblinvoice.invcid = tblpay.invcid)
LEFT JOIN tblinvcdetail
ON tblinvoice.invcid = tblinvcdetail.invcid)
LEFT JOIN tblpaydetail
ON tblpay.payid = tblpaydetail.payid
GROUP BY tblinvoice.invcid,
tblinvoice.invcdate;
But the result is not quite correct
Please help me.
Thanks a lot.
Sample data:
tblInvoice:
invcid customerid invcdate |invcsum(manualy calculated)
18 8 6/30/2012 |$140,000
39 8 7/12/2012 |$170,000
40 8 7/12/2012 |$80,000
43 8 7/14/2012 |$80,000
44 8 7/14/2012 |$80,000
45 8 7/15/2012 |$700,000
46 8 7/17/2012 |$180,000
tblInvcDetail:
ID invccid itemname itemprice itemquantity
19 18 X $70,000 2
92 39 Y $80,000 1
93 39 Z $90,000 1
94 40 Y $80,000 1
97 43 Y $80,000 1
98 44 Y $80,000 1
99 45 W $700,000 1
100 46 Y $80,000 1
101 46 U $100,000 1
tblPay:
payid invcid paydate |AmountSUM(Manually Calculated)
35 18 7/11/2012 |$120,000
40 18 7/12/2012 |$147,000
41 40 7/12/2012 |$84,000
44 44 7/14/2012 |$84,000
46 45 7/15/2012 |$700,000
tblPayDetail:
payid amount
35 $100,000
35 $20,000
40 $147,000
41 $84,000
44 $84,000
46 $700,000
And finally the query result is:
invcid invcdate SumOfInvoice SumOfAmount
18 6/30/2012 $420,000.00 $267,000.00
39 7/12/2012 $170,000.00
40 7/12/2012 $80,000.00 $84,000.00
43 7/14/2012 $80,000.00
44 7/14/2012 $80,000.00 $84,000.00
45 7/15/2012 $700,000.00 $700,000.00
46 7/17/2012 $180,000.00
You can see that the calculation is wrong in the first row (SumOfInvoice column)
and the rest is correct!
How about:
SELECT a.invcid,
a.invcdate,
a.sumofinvoice,
b.sumofamount
FROM (SELECT ti.invcid,
ti.invcdate,
SUM(td.itemprice * td.itemquantity) AS SumOfInvoice
FROM tblinvoice AS ti
LEFT JOIN tblinvcdetail AS td
ON ti.invcid = td.invcid
GROUP BY ti.invcid,
ti.invcdate) a
LEFT JOIN (SELECT tp.invcid,
SUM(tpd.amount) AS SumOfAmount
FROM tblpay AS tp
LEFT JOIN tblpaydetail AS tpd
ON tp.payid = tpd.payid
GROUP BY tp.invcid) b
ON a.invcid = b.invcid