I have two tables:
Table1
id name qty
1 Tedd 6
2 Jim 7
3 Sally 8
4 Victoria 1
Table2
id name qty
1 Tedd 2
2 Jim 2
3 Sally 2
4 Victoria 1
5 Alex 9
I need to select all the rows from Table1. However, if a row exists in Table2 that doesn't exist in Table1, I need to include that in the result set. So, in the end, my query should return this:
id name qty
1 Tedd 6
2 Jim 7
3 Sally 8
4 Victoria 1
5 Alex 9
Is there a way I can do this? Thanks.
You can use a FULL OUTER JOIN:
select
coalesce(t1.id, t2.id) id,
coalesce(t1.name, t2.name) name,
coalesce(t1.qty, t2.id) qty
from table1 t1
full outer join table2 t2
on t1.id = t2.id
See SQL Fiddle with Demo
Related
I have a table with records of the same type with ID's and a grouping. I need to update the id's of table 1 into table 2 based on the record id from largest to smallest using the position.
Table 1
ID
Group
Name
1
A
Apple
2
A
Apple
3
B
Apple
4
B
Apple
Table 2
ID
recordid
position
group
1
1
250
A
2
2
350
A
3
null
450
A
4
null
550
A
5
3
250
B
6
4
350
B
7
null
450
B
8
null
550
B
update table2
set recordid=T1.ID
From Table1 T1
join Table2 T2 on T2.Group=T1.Group
This isn't distinct so I don't think it's right, but I can't figure it out.
where ?????
the problem is you have multiple Id per group , so you have to choose one :
update table2
set recordid= ( select top 1 T1.ID
From Table1 T1
join Table2 T2 on T2.Group=T1.Group
)
where recordid is null
Consider two tables like this
id name
1 john
2 doe
3 jan
device id id devicename purchasedate
1 1 iphone 2018-02-22
2 1 iphone2 2019-02-22
3 1 iphone3 2020-02-22
4 2 iphone4 2019-02-22
5 2 iphone5 2019-02-25
6 3 iphone6 2020-03-15
So the result must be the join of the two tables and only the latest purchased date of a record must be selected. So the expected select result will be like this and if there is a record in the first table with no relationship in the second table, it should not be selected so only inner join can be used.
id name device id device name
1 john 3 iphone3
2 doe 5 iphone5
3 jan 6 iphone6
You can cross apply:
select t1.name, t2.* -- or whatever columns you want
from table1 t1 cross apply
(select top (1) t2.*
from table2 t2
where t2.id = t1.id
order by t2.purchaseddate desc
) t2
I have three tables which look like those:
TABLE 1
id j_id
1 1
2 2
3 3
TABLE 2
id j_id table1_id
1 57 1
2 84 1
3 1 1
4 9 2
5 2 2
and every j has a value in a third table
id value
1 1abc
2 2bcd
3 3abc
57 57abc
84 84abc
9 9abc
I am trying to write a query which will join table 1 and table 2 and use the J value from the third table instead of the j_id, but the problem is that I want to use the j value from the second table if it exists and otherwise use the value from the first table.
in order the make it clearer this is my query result without using the third table:
tbl1.j_id tbl2.j_id
1 1
1 84
1 57
2 2
2 9
3 null
I want the end query result to use the second table's j value unless it is null:
tbl1.j_id tbl2.j_id j_id
1 1 1abc
1 84 84abc
1 57 57abc
2 2 2abc
2 9 9abc
3 null 3abc
(Question and title edits are more than welcome, weren't that sure how to phrase them..)
You can simply JOIN to table3 on the COALESCE of table2.j_id and table1.j_id:
SELECT t1.j_id AS t1_j_id, t2.j_id AS t2_j_id, t3.value
FROM table1 t1
LEFT JOIN table2 t2 ON t2.table1_id = t1.id
JOIN table3 t3 ON t3.id = COALESCE(t2.j_id, t1.j_id)
Output:
t1_j_id t2_j_id value
1 1 1abc
1 57 57abc
1 84 84abc
2 2 2bcd
2 9 9abc
3 null 3abc
Demo on dbfiddle
One solution is to left join table3 twice:
select
t1.j_id,
t2.j_id,
coalesce(t31.value, t32.value) j_value
from
table1 t1
left join table2 t2 on t2.table1_id = t1.id
left join table3 t31 on t31.id = t2.j_id
left join table3 t32 on t32.id = t1.j_id
I have a three tables
Table 1
Id Department
1 A
2 B
3 C
4 D
Table 2
Id DepartId Name
1 1 ABC
2 1 DEF
3 1 ASD
4 2 FGH
5 2 HJK
6 3 ZXC
Table 3
Id Depart Area
1 A pp
2 B
3 C nn
4 D oo
I need the result
Id Depart Name Area
1 A ABC pp
2 B FGH Null
3 C ZXC nn
4 D NULL oo
I need one matching entry from table 2 and table 3 to corresponding entry in the table 1
Do a left join to also get t1 rows without any reference in the t2 table. GROUP BY to get only 1 row per Department.
select t1.id, t1.Department, min(t2.Name)
from t1
left join t2 on t1.id = t2.DepartId
group by t1.id, t1.Department
I think I would do this with a correlated subquery:
select t1.*,
(select t2.name
from t2
where t1.id = t2.DepartId and rownum = 1
) as t2name
from t1;
This saves the overhead of an aggregation. An index on t2(DepartId, name) is optimal for this query.
by the way not the answer to your specific question but if instead of just one you want all the names you can use listagg
SELECT t1.id,
department,
LISTAGG (name, ',') WITHIN GROUP (ORDER BY name) names
FROM t1, t2
WHERE t1.id = t2.departId(+)
GROUP BY t1.id, department
ORDER BY 1
ID Department Names
1 A ABC,ASD,DEF
2 B FGH, HJK
3 C ZXC
4 D
eid name
1 john
2 pal
3 mike
4 michel
id eid mobile address
1 1 9640253265
2 2 9632587412 hellpp
3 3 poplop
4 4 9638523690
5 1 9632589632
6 2 addr
how to get the below output
name mobilecount addresscount
john 2 0
pal 1 2
mike 0 1
michel 1 0
Something like this:
SELECT t1.name,
COUNT(mobile) AS mobilecount,
COUNT(address) AS addresscount
FROM table1 AS t1
JOIN table2 AS t2 ON t1.eid = t2.eid
GROUP BY t1.name
The above query depends on COUNT function not counting NULL values.
Maybe this will help.
select name,SUM(mobilecount) as mobilecount,SUM(addresscount) as addresscount
from
(
select t1.name,
case when isnull(t2.mobile,'')<>'' then count(mobile) else 0 end as
mobilecount,
case when isnull(t2.address,'')<>'' then count(mobile) else 0 end as
addresscount
from table1 t1,table2 t2
where t1.eid = t2.eid
group by t1.name,t2.mobile,t2.address
)employee
group by name order by name