Replacing null values with join - sql

I have two tables
Table1: Table2:
ID: Type: Amount: ID: Amount:
165 Red 300 188 425
167 Red 100 189 500
168 Blue 250 222 129
188 Grey NULL 333 247
189 Grey NULL 369 328
I am trying to replace the null values from table 1 by joining on table 2.
My code results in two amount columns.
LEFT JOIN table2
ON table2.pk = table1.pk
AND table1.Type IS NULL

I think you want:
select t1.id, t1.type, coalesce(t1.amount, t2.amount)
from table1 t1 left join
table2 t2
on t1.id = t2.id;

Hope this helps for your needs
select t1.id,t1.type,isnull(t1.amount,t2.amount) 'Amount' from table1 t1 left join table2 t2 on t1.id = t2.id
you can use isnull() function so that if the first table amount is null then it will take second table value.

Related

Full outer merge of more than two tables in ms sql server to prepare desired table as shown in the example

I have 3 tables as shown below.
t1:
id runs
001 1200
020 600
123 1500
t2:
id wickets
008 4
030 7
123 0
020 6
t3:
id catches
007 4
030
123 2
040 6
I would like to perform FULL OUTER JOIN of all the three tables and prepare the as shown below.
Expected output:
id runs wickets catches
001 1200
020 600 6
123 1500 0 2
008 4
030 7
007 4
040 6
I tried below code and did not works.
SELECT *
FROM t1
FULL OUTER JOIN t2
ON t1.id = t2.id
FULL OUTER JOIN t2.id = t3.id
I did the same using pandas using following code and it worked well.
from functools import reduce
dfl=[t1, t2, t3]
df_merged = reduce(lambda left,right: pd.merge(left,right,on=['id'],
how='outer'), dfl)
You can select the expected columns you want to obtain from each table:
SELECT coalesce(t1.id,t2.id, t3.id), t1.runs, t2.wickets, t3.catches
FROM t1
FULL OUTER JOIN t2 ON t1.id = t2.id
FULL OUTER JOIN t3 ON COALESCE(t1.id, t2.id) = t3.id
You could use UNION ALL in a sub-query and then GROUP BY.
This would give you zeros where there is no value. If this is a problem we could modify the presentation.
If you have another table with all the players we could us LEFT JOIN onto the three tables with
WHERE runs <>'' OR wickets <> '' OR catches <> ''
select
sum(runs) "runs",
sum(wickets) "wickets",
sum(catches) "catches)
from(
select id, runs, 0 wickets, 0 catches from t1
union all
select id, 0, wickets,0 from t2
union all
select id, 0,0, catches from t3
)
group by id,
order by id;

Join all record even not match

I have tables_1 and table_2
table_1
id name cost
100 joe 10
101 bob 20
102 mary 30
table_2
id name
100 joe
101 bob
102 mary
103 tom
I want to join these tables even no match id and expect result
id name cost
100 joe 10
101 bob 20
102 mary 30
103 tom null
My query
select t1.id, t1.name, t1.column1, t1.column2
from Table_1 t1
join Table_1 t2 on t1.id = t2.id
and t1.id <> t2.id
I got nothing return. Need some help. Thank you
It looks like you need a simple outer join
select t2.id, t2.name, t1.cost
from table_2 t2
left join table_1 t1 on t1.id=t2.id
What you need is a right join (or a left join if you reverse the order of tables in the join)
select table_2.id, table_2.name, table_1.cost
from table_1 right join table_2
on table_1.id = table_2.id

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

SQL - Several rows into one

There are 12 rows in the table in total. Every unique record contains of 4 rows. I want the result on 3 rows/records in total having 4 Fields/columns each.
Example Input:
TEST
455
688
987
Texter
567
53
878
Julgranar
765
454
989
Exampel output/result:
Column1 Column2 Column3 Column4
TEST 455 688 987
Texter 567 53 878
Julgranar 765 454 989
There are a few ways depending on some data rules that you have not included, but here is one way using what you gave.
SELECT
t1.Field1,
t2.Field2
FROM Table1 t1
LEFT JOIN Table1 t2 ON t1.FK = t2.FK AND t2.Field1 IS NULL
Another way:
SELECT
t1.Field1,
(SELECT Field2 FROM Table2 t2 WHERE t2.FK = t1.FK AND Field1 IS NULL) AS Field2
FROM Table1 t1

How to display one rows from the two rows

I have type column in my table, type column value is HOT andNOT. from that i want to display HOT and NOT values of the column in to one line.
Example
Table1
Period ID Total
11/2011 101 250
12/2011 102 350
11/2011 103 450
....
Table2
Period ID Type Value
11/2011 101 NOT 500
11/2011 101 HOT 200
12/2011 102 NOT 300
12/2011 102 HOT 200
....
I want to display type (Hot and Not) in to one line
Expected Output
Period ID NOT HOT Total
11/2011 101 500 200 250
12/2011 102 300 200 350
11/2011 103 300 400 450
....
How to make a query.
If I can assume that table1 has a primary key of (Period, ID) and table2 has a primary key of (Period, ID, Type), then you can do:
select
t1.period
, t1.id
, t2n.value [not]
, t2h.value [hot]
, t1.total
from
table1 t1
left join table2 t2n
on t1.period = t2n.period
and t1.id = t2n.id
and t2n.type = 'Not'
left join table2 t2h
on t1.period = t2h.period
and t1.id = t2h.id
and t2h.type = 'Hot'
This will retrieve all rows from table 1, with their corresponding "not" and "hot" counterparts, respective to t2n and t2h above.
Did you try this?
select base.period, base.id, sum( notchild.value ) as notsum, sum( hotchild.value ) as hotsum, base.total
from table1 base
left outer join table2 notchild
on base.period = notchild.period and base.id = notchild.id and notchild.type = 'NOT'
left outer join table2 hotchild
on base.period = hotchild.period and base.id = hotchild.id and hotchild.type = 'HOT'
group by base.period, base.id, base.total
You can use JOIN(Check this) to do this. Join your two tables and perform a SELECT on it.