I have two tables : table_A and table_W. I want to get only the non-matching payment details with the corresponding descriptions. The table are:
table_W
adharno phone descrip_w amount_w
1 11 p1 100
2 22 p1 250
2 22 p2 250
2 22 p3 300
2 33 p1 150
2 33 p2 150
2 33 p3 400
3 55 p1 50
3 66 p1 100
table_A
adharno phone decrip_a amount_a
1 11 p1 110
2 22 p1 150
2 22 p2 150
2 22 p3 400
2 33 p1 250
2 33 p2 250
2 33 p3 300
3 55 p1 100
3 66 p1 50
I am getting the following result.
adharno phone descrip_w amount_w decrip_a amount_a
1 11 p1 100 p1 110
2 22 p1 250 p1 150
2 22 p2 250 p2 150
2 22 p3 300 p3 400
2 33 p1 150 p1 250
2 33 p2 150 p2 250
2 33 p3 400 p3 300
3 55 p1 50 p1 100
3 66 p1 100 p1 50
But the result I am looking is as follows
adharno phone descrip_w amount_w decrip_a amount_a
1 11 p1 100 p1 110
I want to compare the matching descrip, even if the phoneno is different but the adhaarno should be same.
How about:
SELECT w.adharno,
w.phone w_phone,
descrip_w,
amount_w,
a.phone a_phone,
decrip_a,
amount_a
FROM table_w w
JOIN table_a a ON a.adharno = w.adharno
AND w.descrip_w = a.decrip_a
AND (w.phone <> a.phone
OR w.amount_w <> a.amount_a)
Related
So I have a complex situation.
I have a 3 tables:
Product
Resource Name
Resource Type
C1
Bold
E2
Crema
C2
Bold
C3
Bold
Purchase_History
Resource Name
Qty
Cust ID
Date
Batch
C1
7
123
Jun 1
324
C1
7
222
Jun 10
324
C1
7
333
Jun 11
4BZ
C1
7
124
Jun 11
4BZ
C1
7
125
Jun 11
324
C1
7
111
Jun 21
324
C2
7
55
Jun 22
A22
C2
7
1
Jun 24
A22
Inventory
Resource Name
Available
Qty
Batch
C1
1
40
324
C2
1
50
3GC
C1
2
0
4BZ
C2
1
99
A22
E2
1
99
B22
E2
2
0
C22
So I've created a query as below:
Select
p.resourcename
, ph.cust_id
, ph.batch
, case when i.available=1 then 'Yes' when i.available=2 then 'no' else ''end 'In Stock'
from product p
join purchase_history ph on ph.resource_name=p.resource_name
join inventory i on i.batch=ph.batch
where
ph.date >='Jun 1'
ph.date <='Jun 20'
I am getting the following:
Resource Name
Cust Id
Batch
In Stock
C1
123
324
Yes
C1
222
324
Yes
C1
333
4BZ
No
C1
124
4BZ
No
C1
123
324
Yes
What I would like to achieve is the below, where even though the last 2 batch and products are out of the range of transactions, we can still see them as below. I know this is a weird as but essentially the team wants to see what has been sold so far - within the date range - and all product availability status. Is this something achievable?
Resource Name
Cust Id
Batch
In Stock
C1
123
324
Yes
C1
222
324
Yes
C1
333
4BZ
No
C1
124
4BZ
No
C1
123
324
Yes
C2
n/a
3GC
Yes
C2
n/a
A22
Yes
E2
n/a
B22
Yes
E2
n/a
C22
No
you need to use left join with purchase_history table:
Select
p.resourcename
, ph.cust_id
, i.batch
, case when i.available=1 then 'Yes' when i.available=2 then 'no' else ''end 'In Stock'
from product p
join inventory i on i.resource_name=p.resource_name
left join purchase_history ph
on ph.resource_name=p.resource_name
and i.batch=ph.batch
where
ph.date >='Jun 1' and ph.date <='Jun 20'
notice I changes the order of tables for better readability.
I've got a query with three Cross-Applies that gather data from three different tables. The first Cr-Ap assists the 2nd and 3rd Cr-Ap's. It finds the most recent ID of a certain refill for a 'cartridge', the higher the ID the more recent the refill.
The second and third Cr-Ap's gather the SUMS of items that have been refilled and items that have been dispensed under the most recent Refill.
If I run the query for Cr-Ap 2 or 3 separately the output would look something like:
ID Amount
1 100
2 1000
3 100
4 0
5 0
etc
Amount would be either the amount of dispensed or refilled items.
Only I don't want to run these queries separately, I want them next to each other.
So what I want is a table that looks like this:
ID Refill Dispense
1 100 1
2 1000 5
3 100 7
4 0 99
5 0 3
etc
My gut tells me to do
INNER JOIN crossaply2 ON crossapply3.ID = crossapply2.ID
But this doesn't work. I'm still new to SQL so I don't exactly know what I can and can't join, what I do know is that you can use crossapply as a join (sorta?). I think that might be what I need to do here, I just don't know how.
But that's not it, there's another complication, there are certain refills where nothing gets dispensed. In these scenarios the crossapply I wrote for dispenses won't return anything for that refillID. With nothing I don't mean NULL, I mean it just skips the refillID. But I'd like to see a 0 in those cases. Because it just skips over those ID's I can't get COALESCE or ISNULL to work, this might also complicate the joining of these two applies. Because an INNER JOIN would skip any line where there is no Dispensed amount, even though there is a Refilled amount Id like to see.
Here is my code:
-- Dispensed SUM and Refilled SUM combined
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id]
,Refills.Refilled
,Dispenses.Dispensed
FROM [CartridgeRefill]
CROSS APPLY(
SELECT MAX([CartridgeRefill].[Id]) AS RecentRefillID
FROM [CartridgeRefill]
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS RecentRefill
CROSS APPLY(
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id] AS RefilledID
,SUM([CartridgeRefillMedication].[Amount]) AS Refilled
FROM [CartridgeRefillMedication]
INNER JOIN [CartridgeRefill] ON [CartridgeRefillMedication].[FK_CartridgeRefill_Id] = [CartridgeRefill].[Id]
WHERE [CartridgeRefillMedication].[FK_CartridgeRefill_Id] = RecentRefill.RecentRefillID
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS Refills
CROSS APPLY(
SELECT [CartridgeRefill].[FK_CartridgeRegistration_Id] AS DispensedID
,SUM([CartridgeDispenseAttempt].[Amount]) AS Dispensed
FROM [CartridgeDispenseAttempt]
INNER JOIN [CartridgeRefill] ON [CartridgeDispenseAttempt].[FK_CartridgeRefill_Id] = [CartridgeRefill].[Id]
WHERE [CartridgeDispenseAttempt].[FK_CartridgeRefill_Id] = RecentRefill.RecentRefillID
GROUP BY [CartridgeRefill].[FK_CartridgeRegistration_Id]
) AS Dispenses
GO
The output of this code is as follows:
1 300 1
1 300 1
1 200 194
1 200 194
1 200 8
1 200 8
1 0 39
1 0 39
1 100 14
1 100 14
1 200 1
1 200 1
1 0 28
1 0 28
1 1000 102
1 1000 102
1 1000 557
1 1000 557
1 2000 92
1 2000 92
1 100 75
1 100 75
1 100 100
1 100 100
1 100 51
1 100 51
1 600 28
1 600 28
1 200 47
1 200 47
1 200 152
1 200 152
1 234 26
1 234 26
1 0 227
1 0 227
1 10 6
1 10 6
1 300 86
1 300 86
1 0 194
1 0 194
1 500 18
1 500 18
1 1000 51
1 1000 51
1 1000 56
1 1000 56
1 500 48
1 500 48
1 0 10
1 0 10
1 1500 111
1 1500 111
1 56 79
1 56 79
1 100 6
1 100 6
1 44 134
1 44 134
1 1000 488
1 1000 488
1 100 32
1 100 32
1 100 178
1 100 178
1 500 672
1 500 672
1 200 26
1 200 26
1 500 373
1 500 373
1 100 10
1 100 10
1 900 28
1 900 28
2 900 28
2 900 28
2 900 28
etc
It is total nonsense that I can't do much with, it goes on for about 20k lines and goes through all the ID's, eventually.
Any help is more than appreciated :)
Looks like overcomplicated a bit.
Try
WITH cr AS (
SELECT [FK_CartridgeRegistration_Id]
,MAX([CartridgeRefill].[Id]) RecentRefillID
FROM [CartridgeRefill]
GROUP BY [FK_CartridgeRegistration_Id]
)
SELECT cr.[FK_CartridgeRegistration_Id], Refills.Refilled, Dispenses.Dispensed
FROM cr
CROSS APPLY(
SELECT SUM(crm.[Amount]) AS Refilled
FROM [CartridgeRefillMedication] crm
WHERE crm.[FK_CartridgeRefill_Id] = cr.RecentRefillID
) AS Refills
CROSS APPLY(
SELECT SUM(cda.[Amount]) AS Dispensed
FROM [CartridgeDispenseAttempt] cda
WHERE cda.[FK_CartridgeRefill_Id] = cr.RecentRefillID
) AS Dispenses;
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.
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 |
I am using the following statement;
SELECT RESV_ID, BOOKING_CUS_ID, ACC_ID,
(SELECT F.FLI_PRICE FROM FLIGHT F WHERE F.FLI_ID = R.IN_FLIGHT_ID) AS DEPART_FLIGHT_PRICE,
(SELECT F1.FLI_PRICE FROM FLIGHT F1 WHERE F1.FLI_ID = R.OUT_FLIGHT_ID) AS RETURN_FLIGHT_PRICE,
(SELECT AC.ACC_PRICEPN FROM ACCOMMODATION AC WHERE AC.ACC_ID = R.ACC_ID) AS ACCOMMODATION_PRICE
FROM HOLIDAY_RESERVATION R;
to yield the following results;
RESV_ID BOOKING_CUS_ID ACC_ID DEPART_FLIGHT_PRICE RETURN_FLIGHT_PRICE ACCOMMODATION_PRICE
---------- -------------- ---------- ------------------- ------------------- -------------------
1 1 2 520 450 350
2 3 4 250 150 150
3 5 6 290 300 450
4 7 7 399 450 650
5 9 365 345
6 11 558 460
7 13 250 250
8 15 550 550
9 17 25 250
10 19 19 450
10 rows selected.
Question:
How do I sum up the price fields, SOME PRICES ARE NOT AVAILABLE because a reservation was either made for accommodation only or flight only, hence both values will not be present always and this is where the issue lies
DEPART_FLIGHT_PRICE RETURN_FLIGHT_PRICE ACCOMMODATION_PRICE
Furthermore:
I wish to insert or update the SUM of those three values into a SUBTOTAL in the reservation table, perhaps by using select into or update, I have spent a whole day trying to do this but my skills are limited. any help will be greatly appreciated.
Flight table
FLI_ID FLI_CO FLI_AIRCRA DEPT_AIRPORT ARRV_AIRPORT DEPT_TIME ARRV_TIME FLI_PRICE
1 BD425 Boeing 707 1 12 18-MAR-12 02.24.00 AM 18-MAR-12 06.24.00 AM 520
2 LX345 Beriev 30 6 7 20-MAR-12 03.30.00 PM 20-MAR-12 04.20.00 PM 250
3 NZ4445 Boeing 720 9 14 25-MAR-12 09.00.00 AM 25-MAR-12 05.00.00 PM 290
4 TP351 Boeing 767 10 15 25-MAR-12 11.25.00 AM 25-MAR-12 03.35.00 PM 399
5 BA472 Boeing 720 5 14 26-MAR-12 01.05.00 PM 26-MAR-12 04.15.00 PM 365
Accommodation
ACC_ID ACC_TYPE_CODE ACC_DESC ACC_PRICEPN ACC_ROOMS RESORT_ID ACC_ADDR CITY_ID
1 1 Three bedroom bungalow near theme park 500 3 1
2 1 Two bedroom bungalow next to disney house 350 2 1
3 1 One bedroom bungalow with lake view 250 2 2
4 2 One bedroom chalet near the lake 150 1 2
5 2 Four bedroom chalet near the tree house 600 4 3
Reservation
RESV_ID EMP_ID BOOKING_CUS_ID RESV_DATE HOLIDAY_S HOLIDAY_E IN_FLIGHT_ID OUT_FLIGHT_ID IN_FLIGHT_SEATS_NO OUT_FLIGHT_SEATS_NO ACC_ID SUBTOTAL
1 338 1 16-FEB-12 18-MAR-12 20-APR-12 1 11 2 2 2
2 335 3 10-JAN-12 20-MAR-12 22-APR-12 2 12 2 2 4
3 338 5 05-MAR-12 25-MAR-12 26-APR-12 3 13 2 2 6
4 328 7 02-JAN-12 25-MAR-12 25-APR-12 4 14 2 2 7
5 311 9 20-JAN-12 26-MAR-12 21-APR-12 5 15 2 2
6 317 11 07-JAN-12 27-MAR-12 22-APR-12 6 16 2 2
7 344 13 29-FEB-12 15-MAR-12 12-APR-12 7 17 2 2
8 326 15 11-JAN-12 18-MAR-12 12-APR-14 8 18 2 2
9 329 17 16-JAN-12 19-MAR-12 17-APR-12 25
10 323 19 18-FEB-12 20-MAR-12 21-APR-12 19
Okay I managed to yield the results that i wanted
SELECT HR.RESV_ID, F_IN.FLI_ID, F_IN.FLI_PRICE, F_OUT.FLI_ID, F_OUT.FLI_PRICE, AC.ACC_ID, AC.ACC_PRICEPN, NVL(F_IN.FLI_PRICE,0)+NVL(F_OUT.FLI_PRICE,0)+NVL(AC.ACC_PRICEPN,0) AS TOTAL
FROM HOLIDAY_RESERVATION HR
LEFT JOIN FLIGHT F_IN ON HR.IN_FLIGHT_ID = F_IN.FLI_ID
LEFT JOIN FLIGHT F_OUT ON HR.OUT_FLIGHT_ID = F_OUT.FLI_ID
LEFT JOIN ACCOMMODATION AC ON HR.ACC_ID = AC.ACC_ID
ORDER BY HR.RESV_ID;
YIELDS
RESV_ID FLI_ID FLI_PRICE FLI_ID FLI_PRICE ACC_ID ACC_PRICEPN TOTAL
---------- ---------- ---------- ---------- ---------- ---------- ----------- ----------
1 1 500 11 555 2 350 1405
2 2 150 12 253 4 150 553
3 3 300 13 345 6 450 1095
4 4 450 14 343 7 650 1443
5 5 345 15 242 587
6 6 460 16 460 920
7 7 250 17 250 500
8 8 550 18 550 1100
9 25 250 250
10 19 450 450
And the following statement is to update the reservation table.
Thanks to Leigh Riffel from DBA stackxchange for the following code
UPDATE HOLIDAY_RESERVATION R SET SUBTOTAL =
NVL((SELECT F.FLI_PRICE FROM FLIGHT F WHERE F.FLI_ID = R.IN_FLIGHT_ID), 0) +
NVL((SELECT F.FLI_PRICE FROM FLIGHT F WHERE F.FLI_ID = R.OUT_FLIGHT_ID), 0) +
NVL((SELECT AC.ACC_PRICEPN FROM ACCOMMODATION AC WHERE AC.ACC_ID = R.ACC_ID), 0);
Now the subtotal is populated with the values obtained from the sum performed above >>
RESV_ID EMP_ID BOOKING_CUS_ID RESV_DATE HOLIDAY_S HOLIDAY_E IN_FLIGHT_ID OUT_FLIGHT_ID IN_FLIGHT_SEATS_NO OUT_FLIGHT_SEATS_NO ACC_ID SUBTOTAL
---------- ---------- -------------- --------- --------- --------- ------------ ------------- ------------------ ------------------- ---------- ----------
1 338 1 16-FEB-12 18-MAR-12 20-APR-12 1 11 2 2 2 1405
2 335 3 10-JAN-12 20-MAR-12 22-APR-12 2 12 2 2 4 553
3 338 5 05-MAR-12 25-MAR-12 26-APR-12 3 13 2 2 6 1095
4 328 7 02-JAN-12 25-MAR-12 25-APR-12 4 14 2 2 7 1443
5 311 9 20-JAN-12 26-MAR-12 21-APR-12 5 15 2 2 587
6 317 11 07-JAN-12 27-MAR-12 22-APR-12 6 16 2 2 920
7 344 13 29-FEB-12 15-MAR-12 12-APR-12 7 17 2 2 500
8 326 15 11-JAN-12 18-MAR-12 12-APR-14 8 18 2 2 1100
9 329 17 16-JAN-12 19-MAR-12 17-APR-12 25 250
10 323 19 18-FEB-12 20-MAR-12 21-APR-12 19 450
Subsequently the code was added to a trigger (which was the original intention)
CREATE OR REPLACE TRIGGER HR_SUBTOTAL
BEFORE INSERT OR UPDATE ON HOLIDAY_RESERVATION
FOR EACH ROW
BEGIN
SELECT
NVL((SELECT F.Fli_Price FROM Flight F WHERE F.Fli_ID = :new.In_Flight_ID), 0) +
NVL((SELECT F.Fli_Price FROM Flight F WHERE F.Fli_ID = :new.Out_Flight_ID), 0) +
NVL((SELECT AC.Acc_PricePn FROM Accomodation AC WHERE AC.Acc_ID = :new.Acc_ID), 0)
INTO :new.Subtotal
FROM dual;
END;
/
For the SUM, assuming you want to treat NULL values as 0, you'd just need to do an NVL on the numbers
NVL( DEPART_FLIGHT_PRICE, 0 ) +
NVL( RETURN_FLIGHT_PRICE, 0 ) +
NVL( ACCOMMODATION_PRICE, 0 )
As for the UPDATE, it sounds like you just need a correlated UPDATE statement.
UPDATE reservation r
SET subtotal = (SELECT (SELECT NVL( DEPART_FLIGHT_PRICE, 0 ) +
NVL( RETURN_FLIGHT_PRICE, 0 ) +
NVL( ACCOMMODATION_PRICE, 0 )
FROM (SELECT RESV_ID,
BOOKING_CUS_ID,
ACC_ID,
(SELECT F.FLI_PRICE
FROM FLIGHT F
WHERE F.FLI_ID = R.IN_FLIGHT_ID) AS DEPART_FLIGHT_PRICE,
(SELECT F1.FLI_PRICE
FROM FLIGHT F1
WHERE F1.FLI_ID = R.OUT_FLIGHT_ID) AS RETURN_FLIGHT_PRICE,
(SELECT AC.ACC_PRICEPN
FROM ACCOMMODATION AC
WHERE AC.ACC_ID = R.ACC_ID) AS ACCOMMODATION_PRICE
FROM dual));
You are asking:
How do I sum up the price fields, as you can see some of them can have nulls.
DEPART_FLIGHT_PRICE RETURN_FLIGHT_PRICE ACCOMMODATION_PRICE
Just enclose them in NVL function as follows:
NVL(DEPART_FLIGHT_PRICE, 0)
and then sum them up.
For the second part, what you need is a MERGE statement. A good example is at http://www.oracle-developer.net/display.php?id=203