Any cleaner or alternate way to write sql join script - sql

I have following tables:
Table2
StudentNumbers ExamType
------------------------
1234 1
2343 2
3345 5
3454 1
5465 2
...
Table1
StudentNumbers ExamType ExamDate School Area Info
------------------------------------------------------------------
1234 1 0825 warren ny 0x504B03042D0
1234 1 0829 north nj 0x63D86E1FFFF
1233 2 0921 north nj 0xA001400646F
2343 1 0922 warren ny 0x01400646174
2343 1 0925 north ny 0x100100070se
...
I am trying to write a query to get following results:
StudentNumbers ExamType ExamDate School Area Info
-----------------------------------------------------------------
1234 1 0829 north nj 0x63D86E1FFFF
2343 1 0925 north ny 0x100100070se
I wrote following query:
Select t1.StudentNumbers, t1.ExamDate, t1.School, t1.Info, t1.ExamType
from Table1 as t1
Join(
Select ts.StudentNumbers, max(ts.ExamDate) as ExamDate
from Table2 as ts
Join Table1 as pl on
ts.StudentNumbers = pl.StudentNumbers where ts.ExamType = pl.ExamType
group by ts.StudentNumbers
) as t2 on t1.StudentNumbers = t2.StudentNumbers
and t1.ExamDate = t2.ExamDate
Above query works and gives me the result i want that is max ExamDate for particular ExamType based on Table2. But is using multiple joins best way in this aggregate method? Or is there a cleaner option.

Your query is good, but I think to use Table2 table outside subquery would be better option.
SELECT *
FROM (
SELECT StudentNumbers, ExamType, MAX(ExamDate) AS ExamDate
FROM Table1
GROUP BY StudentNumbers, ExamType
) t1 JOIN Table1 t2 ON t1.StudentNumbers = t2.StudentNumbers
AND t1.ExamType = t2.ExamType AND t1.ExamDate = t2.ExamDate
WHERE EXISTS(
SELECT 1
FROM Table2 t3
WHERE t1.StudentNumbers = t3.StudentNumbers
AND t1.ExamType = t3.ExamType
)

SELECT
t1.*
FROM Table1 t1
INNER JOIN Table2 t2
ON t1.StudentNumbers = t2.StudentNumbers
WHERE t1.ExamDate = (SELECT MAX(ExamDate) FROM Table1 WHERE StudentNumbers = t1.StudentNumbers)
ORDER BY t1.StudentNumbers ASC
Might not be the most efficient solution though.

Related

How to Join 3 tables based on 2 columns from one table in presto?

I Have 3 tables as below. In table1, if value in column id is present then join that column with other tables, if null I want to join with ref column from table 1 with other tables. What is the best way to do this
table1
Name id ref
abc 123
abc 456
edc 345 432
asd 678
table 2
city id ref
NY 123
WA 875
CA 345 432
SA 678
table 3
city orders
NY 78954
WA 123546
CA 789
SA 1
I want below result: ABC has 123 in id hence NY. ASD has 678, so considered ref column in table1 to join with other 2 tables
Name city order
ABC NY 78954
EDC CA 789
ASD SA 1
You can use left joins for this purpose:
select t1.*, t3.city, t3.count
from table1 t1 left join
table2 t2
on t1.id = t2.id left join
table2 t2r
on t1.ref = t2.ref and t1.id is null left join
table3 t3
on t3.city = coalesce(t1.city, t2.city);
Note: This returns all rows from table1, even those with no match in either column. If this is an issue, add:
where t2.id is not null or t2.ref is not null

Join two tables with switch case in order to avoid one to many join

I have two tables, t1 and t2.
Table t1:
Name address id
---- ------- --
rob 32 cgr 12
mary 31 lmo 42
tom axel St 2
Table t2:
ID Flag expense
-- ---- --------
12 Shop 1200
12 Educ 14000
42 educ 4000
Now I will have to create a table which will have attributes from t1 plus two more attributes that is expense in shop and expense in educ
Table t3
Name address id Shop_ex Educ_ex
---- ------- -- ------- -------
rob 32 cgr 12 1200 14000
mary 31 lmo 42 NULL 4000
tom axel st 2 NULL NULL
How to accomplish this?
I tried doing a left join t2 with switch case but it gives me multiple record as the join is becoming one to many.
select
t1.name, t1.address, t1.id,
case
when t2.flag = "shop" then t2.expense
else null
end as shop_ex
case
when t2.flag = "educ" then t2.expense
else null
end as educ_ex
from
t1
left join
t2 on (t1.id = t2.id)
It seems I will have to convert t2 table first before joining, to have a single record on the basis of flag. But I am not sure how to do that.
Please mind the tables are huge and optimized query will be nice.
Please suggest.
You only need to join the first table to the second one, twice:
SELECT t1.Name, t1.address, t1.id, t2a.expense AS Shop_ex, t2b.expense AS Educ_ex
FROM table1 t1
LEFT JOIN table2 t2a
ON t2a.ID = t1.id AND t2a.Flag = 'Shop'
LEFT JOIN table2 t2b
ON t2b.ID = t1.id AND t2b.Flag = 'Educ'
Demo

Joining table get the first data on first table if duplicate

Hi i have table1 and table2.
table1 is the logtime table of employees and table2 is the groupcode of the employee.
On table1 some employees has duplicate time in because they time in multiple time to just to secure their time in.
Table1
ID EMPID Time_IN
1 001 7:01 AM
2 004 7:04 AM
3 034 7:10 AM
4 034 7:11 AM
5 019 7:11 AM
6 019 7:12 AM
Table2
ID empID GroupName
1 001 AA
2 004 AB
3 034 AA
4 019 AA
result
GroupName CNT
AA 5
AB 1
Expected result
GroupName CNT
AA 3
AB 1
current query
Select b.GroupName, count(*) as cnt
from table1 a
inner join table2 b
on a.EMPID = b.empID
Group by b.GroupName
How can i achive as expected result above?
Thankyou in advance.
you can use distinct count as follows:
select t2.groupname, count(distinct empid) as cnt
from table1 t1 join table2 t2
on t1.empid = t2.empid
group by t2.groupname
The join is superfluous for the question you have asked:
select t2.GroupName, count(*) as cnt
from table2 t2
group by t2.GroupName;
This is much more efficient than joining and using count(distinct). You probably really have a different question, which should be asked as a new question.

fusion 2 tables with inner join

in my database i have 2 tables.
table1
i have ID and NAMES
table2
i have ID, IDASSOCIATION, QUANTITY
so
i have 2 names in table1:
john and tom
and in table2 i have 3 lignes
john, 1
tom, 1
john, 1
nombre one is the quantity
in my result i want get
john = 2
and tom = 1
so i do this:
sql = "SELECT t1.*, t2.IDASSOCIATION, (SELECT SUM(t2.id_qte) FROM associationdepotarticle t2 WHERE t1.fusiontable = t2.fusiontable GROUP BY t2.IDASSOCIATION) as id_qte FROM articletable t1, associationdepotarticle t2";
but i not get this:
john = 2
tom = 1
why ? what i will do, i need correction please
You can just join the tables together and use sum:
select t1.name, sum(t2.quantity)
from table1 t1
join table2 t2 on t1.id = t2.idassociation
group by t1.name
It's not completely clear from your sample data what to join on, but I assume it's the idassociation field. If you want to return those names in table1 which aren't in table2, then use an outer join.

SQL help for inner query

Sorry for repost but this will help you understand the scnario better-
For each member, there can be two types of addresses (mail and legal- based on two diff indicators). My goal is extract both the adress and show them in one column for each member id.
TABLE1
Address_key(PK) Country City PostCode
1 UK London 1111
2 US New York 2222
3 Spain Madrid 3333
4 France Paris 4444
5 Swiss Munich 5555
Table 2
Member Key(PK) Memebr ID
1 1
2 2
3 3
4 2
Table3
Address Key Member Key Mail Ind Legal Ind
1 1 Y N
2 1 N Y
3 2 Y Y
4 4 N Y
5 4 Y N
My goal is to get the mail address(based on mail ind) and legal adress(based on legal ind) for each member id.
SO my output should be -
Member Key Member ID Country City Postcode Legal Country Legal City Legal Postcode
1 1 UK London 1111 US New York 2222
2 2 Spain Madrid 3333 Spain Madrid 3333
4 2 Swiss Munich 5555 France Paris 4444
Can anyone help how to achieve this ? I am using oracle 10m toad 9.0
Which is better to use: Inner query or simple join ?
Something like the below? With your column naming i'm a little confused with Table2 Member Key(PK) , Memebr ID and what their relationship is to Table 3 Member ID. My best guess is below:
Select [Member Key], t2.[Member Id], t1.*
FROM TABLE2 t2
INNER JOIN TABLE3 t3 on t3.[Member Key] = t2.[Member Id]
INNER JOIN TABLE1 t1 on t1.[Address Key] = t3.[Address Key]
Since you have two types of addresses, you could join twice to TABLE3, once for the Mailing address and next for the legal address.
select T2.Member_Key, T2.Member_id
,coalesce(T1A.Country,''), coalesce(T1A.City,''), coalesce(T1A.PostCode,'')
,coalesce(T1B.Country,''), coalesce(T1B.City,''), coalesce(T1B.PostCode,'')
from Table2 T2
left join Table3 T3A on T2.Member_Key=T3A.Member_Key and T3A.Mail_Ind='Y'
left join Table1 T1A on T3A.Address_key = T1A.Address_Key
left join Table3 T3B on T2.Member_Key=T3B.Member_Key and T3B.Legal_Ind='Y'
left join Table1 T1B on T3B.Address_key = T1B.Address_Key
Another way would be to join once and use a CASE expression, thus:
select T2.Member_Key, T2.Member_id
,max(coalesce(CASE T3.Mail_Ind='Y' then T1.Country Else '' End,''))
, ... etc.
,max(coalesce(CASE T3.Legal_Ind='Y' then T1.Country Else '' End,''))
, ... etc.
from Table2 T2
left join Table3 T3 on T2.Member_Key=T3.Member_Key
left join Table1 T1A on T3.Address_key = T1.Address_Key
group by Member_Key, Member_id