Joining two tables in Oracle sql - sql

I have 2 tables. One of the tables have 7 values and the other table has 5 values. These tables have their primary keys in common. I want to join both tables this way:
If I have a Table
English French
-------------------- --------------------
one Un
two Deux
three Trois
four Quatre
four Quattro
five Cinq
five Cinco
And another one:
English French
-------------------- --------------------
one aaaaa
two bbbbb
three ccccc
four
five
I want to have a table like this:
English French
-------------------- --------------------
one Un
one aaaaa
two Deux
two bbbb
three Trois
three ccccc
four Quatre
four Quattro
four --------
five Cinq
five Cinco
five ----------
I tried using join but it does a linear combination of the values four and five. How can I go about doing this? Thanks.
Edit: SQL query:
SELECT l.date_location, l.duree, r.km_restitution, r.km_parcouru
FROM locations l, restitutions r
UNION
SELECT l.num_client, l.date_location, l.duree, r.km_restitution, r.km_parcouru
FROM locations l, restitutions r
id_agence num_immatriculation num_client km_restitution km_parcouru state date_restitution
1 406BON69 1002 30000 1000 BON 29-MAY-10
3 785CIM13 1001 56580 80 BON 09-AUG-08
5 800BBB75 1000 2020 20 BON 24-APR-11
4 307VXN78 1000 20040 40 BON 28-JAN-11
2 290UTT92 1004 30030 30 BON 01-AUG-10
5 777SET13 1005 4030 30 BON 26-APR-11
2 179CLV92 1004 15015 15 BON 03-FEB-11
5 400AAA75 1003 1020 20 BON 18-SEP-11
5 666NEF69 1004 3040 40 BON 15-APR-11
2 111AAA75 1001 20020 20 BON 21-DEC-09
1 333CCC78 1001 43250 40 BON 27-DEC-09
2 260CDE95 1003 79000 430 BON 10-SEP-09
4 307VXN78 1003 20090 90 BON 11-FEB-11
1 123ABC78 1003 10010 10 BON 04-OCT-10
1 222BBB77 1001 9050 50 BON 23-DEC-09
Locations
id_agence num_immatricul num_client duree date_location
2 406BON69 1002 20 10-MAY-10
3 785CIM13 1001 3 07-AUG-08
5 800BBB75 1000 7 18-APR-11
4 307VXN78 1000 5 24-JAN-11
1 290UTT92 1004 1 31-JUL-10
5 777SET13 1005 4 23-APR-11
1 179CLV92 1004 5 30-JAN-11
5 400AAA75 1003 2 17-SEP-11
2 123ABC78 1003 4 01-OCT-10
5 666NEF69 1004 5 11-APR-11
1 111AAA75 1001 2 20-DEC-09
1 222BBB77 1001 2 22-DEC-09
1 333CCC78 1001 3 25-DEC-09
1 260CDE95 1003 10 01-SEP-09
4 307VXN78 1003 13 30-JAN-11
2 123ABC78 1003 8 20-NOV-11
2 406BON69 1002 10 20-NOV-11
Desired Result
id_agence num_immatricul num_client duree date_location date_restitution
2 406BON69 1002 20 10-MAY-10 date_restitution
3 785CIM13 1001 3 07-AUG-08 date_restitution
5 800BBB75 1000 7 18-APR-11 date_restitution
4 307VXN78 1000 5 24-JAN-11 date_restitution
1 290UTT92 1004 1 31-JUL-10 date_restitution
5 777SET13 1005 4 23-APR-11 date_restitution
1 179CLV92 1004 5 30-JAN-11 date_restitution
5 400AAA75 1003 2 17-SEP-11 date_restitution
2 123ABC78 1003 4 01-OCT-10 date_restitution
5 666NEF69 1004 5 11-APR-11 date_restitution
1 111AAA75 1001 2 20-DEC-09 date_restitution
1 222BBB77 1001 2 22-DEC-09 date_restitution
1 333CCC78 1001 3 25-DEC-09 date_restitution
1 260CDE95 1003 10 01-SEP-09 date_restitution
4 307VXN78 1003 13 30-JAN-11 date_restitution
2 123ABC78 1003 8 20-NOV-11 ----------------
2 406BON69 1002 10 20-NOV-11 ---------------
Apart from the column name, where i put date_restitution contains real dates.

You could use a UNION:
select English, French from Table1
UNION ALL
select English, French from Table2
or a full outer join
select distinct coalesce(T1.English, T2.English), coalesce(T1.French, T2.French)
from Table1 T1
full outer join Table2 T2 on T1.English = T2.English
EDIT:
Assuming you want restitutions.date_restitution to appear in place of date_location for restitution records -
SELECT l.num_client, l.date_location, l.duree, to_number(null) km_restitution, to_number(null) km_parcouru
FROM locations l
UNION ALL
SELECT r.num_client, r.date_restitution date_location, 0 duree, r.km_restitution, r.km_parcouru
FROM restitutions r
FURTHER EDIT (based on supplied results):
select l.id_agence,
l.num_immatricul,
l.num_client,
l.duree,
l.date_location,
decode(r.date_restitution, NULL,'----------------', 'date_restitution')
as date_restitution -- or just r.date_restitution
from location l
left outer join restitution r
on l.id_agence = r.id_agence and
l.num_immatricul = r.num_immatricul and
l.num_client = r.num_client and
l.date_location <= r.date_restitution

You actually need a union:
SELECT English, French FROM T1
UNION
SELECT English, French FROM T2
If you don't care about duplicates, you can use UNION ALL
Edit after OP's comment:
SELECT l.num_client, l.id_agence, l.num_immatricul
FROM locations l
UNION
SELECT r.num_client, r.id_agence, r.num_immatriculation
FROM restitutions r

The following should do it.
SELECT tab1.English, tab1.French
UNION
SELECT tab2.English, tab2.French

For other readers who might have the same problem. From the experience I had with this problem, it would be a good idea to join tables locations and restitutions since both of them have almost the same attributes and data. I finally decided in changing my database and creating a new table that contains both the attributes of location and restitution and setting some not availabe values to NULL. This would reduce a lot of joins between tables and queries would be easier to handle.

Related

SQL query to select specific fields, process sum and count from two tables

i have these two tables
ORDERS
id order_id e_id e_name
1 1000 1001 Tom
2 1009 1001 Tom
3 1010 1001 Tom
4 1011 1002 Parker
5 1012 1002 Parker
6 1013 1003 Rohan
Transactions
id order_id amount status
1 1000 100 success
2 1009 80 success
3 1010 100 failed
4 1011 50 success
6 1012 50 success
7 1013 100 failed
i would like to join two tables, select fields, process sum count and filter like this
e_id e_name amount_sum total_counts total_success_amount success_count
1001 Tom 280 3 180 2
1002 Parker 100 2 100 2
1003 Rohan 100 1 0 0
this is what i tried
use card;
SELECT COUNT(orders.order_id) as `total_counts`,
COUNT(CASE WHEN transactions.status = 'success' THEN 1 END) as `success_count`,
SUM(0 + transactions.amount) as `amount_sum`, orders.e_id,
orders.e_name
FROM orders
LEFT JOIN transactions
ON transactions.order_id=orders.order_id
GROUP BY (orders.e_id), (orders.order_id),
(orders.e_name), (transactions.amount), (transactions.status);
i tried many queries also not able to achieve it. Suggest me query to get my operation.

how to get rows with count of occurence (Frequency) in the table

My Database Table is having this type of data
Table Name : Logs
ID ALBUMID GENREID
1 1005 5
1 1008 5
1 1006 4
1 1005 5
1 1007 5
1 1007 4
1 1008 5
1 1008 5
1 1005 5
1 1005 4
1 1005 5
and the result I am expecting is for get - Top 2 Album id with frequency count for GenreId 5 which have maximum frequency..
Result :
AlbumId Frequency
1005 4
1008 3
here is SQL Fiddle Link http://sqlfiddle.com/#!6/aaa9e/13
Please try:
select top 2 ALBUMID, COUNT(*) Frequency
from tbl
where GENREID=5
group by ALBUMID
order by 2 desc

How to combine queries using Access sql

I have a table like below and i'm trying to select 1 series EID's i.e 1001,1002,1003,1004,1005 and 2 series EID's as seperate queries
EID PCNum
1001 8.6
1002 10
1003 9
1004 8
1005 7
2001 4
2002 1
2003 2
2004 3
2005 6
3001 8
3002 0
3003 7
3004 4
3005 4
And queries combined like below
EID PCNum EID PCNum EID PCNum
1001 8.6 2001 4 3001 8
1002 10 2002 1 3002 8
1003 9 2003 2 3003 8
1004 8 2004 3 3004 8
1005 7 2005 6 3005 8
How do i specify that in a sql query? Any suggestions? I tried UNION but giving some errors.
Normally, you would have a column which would separate out EID from series, leaving you with just values like 001, 002, etc.
In this case you could JOIN the data on itself +1000 times the series number. Something like this:
SELECT
t1.EID, t1.PCNum,
t2.EID, t2.PCNum,
t3.EID, t3.PCNum
FROM
table_name t1
INNER JOIN table_name t2 on t1.EID+1000 = t2.EID
INNER JOIN table_name t3 on t1.EID+2000 = t3.EID
WHERE t1.EID BETWEEN 1000 AND 1999
ORDER BY t1.EID

Please help me to solve this [duplicate]

This question already has an answer here:
How can I perform this aggregate?
(1 answer)
Closed 9 years ago.
I have crated two table one is cutomer and other one is ord
select * from customers;
Customer table
1 101 jun 23 yyyy 15000
2 102 jas 24 zzzz 10000
3 103 fat 20 kkkk 20000
4 104 jini 40 llll 30000
5 105 michael 30 dddd 25000
6 106 das 25 hhhh 10000
7 107 vijay 26 mmmm 12000
8 108 thanku 31 jjjj 26000
9 109 vishnu 34 gggg 24000
10 110 vas 28 ffff 18000
select * from ord;
This is order table
1 12/11/2013 1:00:00 AM 102 2500
2 202 12/11/2013 4:14:17 AM 102 3000
3 203 12/9/2013 9:18:16 PM 103 2000
4 204 12/8/2013 12:00:00 PM 102 1000
5 205 12/24/2013 107 2000
This is tha union command that I have used
select c.name,c.salary,o.amount
from CUSTOMERS c
inner join ord o
on c.id=o.customer_id;
then the resulting table is
1 jas 10000 1000
2 jas 10000 3000
3 jas 10000 2500
4 fat 20000 2000
5 vijay 12000 2000
I want resulting table like this
1 jas 10000 6500
2 fat 20000 2000
3 vijay 12000 2000
plz help me for solving this.
group by c.name, c.salary with sum(salary) is what you want:
select c.name, c.salary, sum(o.amount )
from CUSTOMERS c
inner join ord o on c.id=o.customer_id
group by c.name, c.salary;
try this if it will work.
select c.name,c.salary,sum(o.amount)
from CUSTOMERS c
inner join ord o
on c.id=o.customer_id
group by 1,2;
Thanks.
select c.name,c.salary,SUM(o.amount )
from CUSTOMERS c
inner join ord o
on c.id=o.customer_id
GROUP BY c.name,c.salary
I think this will work
Use Left Join or RIGHT JOIN
select c.name,c.salary,o.amount
from CUSTOMERS c
left join ord o
on c.id=o.customer_id;

Update or Select into ORACLE

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