How to display one rows from the two rows - sql

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.

Related

Full outer join without on condition

New to SQL.
I have two SQL tables T1 and T2 which looks like the following
T1
customer_key X1 X2 X3
1000 60 10 2018-02-01
1001 42 9 2018-02-01
1002 03 1 2018-02-01
1005 15 1 2018-02-01
1002 32 2 2018-02-05
T2
customer_key A1 A2 A3
1001 20 2 2018-02-17
1002 25 2 2018-02-11
1005 04 1 2018-02-17
1009 02 0 2018-02-17
I want to get T3 as shown below by joining T1 and T2 and filtering on T1.X3 = '2018-02-01'
and T2.A3 = '2018-02-17'
T3
customer_key X1 X2
1000 60 10
1001 42 9
1005 15 1
1009 null null
I tried doing full outer join in the following way
create table T3
AS
select T1.customer_key, T3.customer_key, T1.X1, T1.X2
from T1
full outer join T2
on T1.Customer_key = T2.customer_key
where T1.X3 = '2018-02-01' and T2.A3 = '2018-02-17'
It returns lesser number of rows than the total records that satisfying the where clause. Please advice
Full outer join with filtering is just confusing. I recommend filtering in subqueries:
select T1.customer_key, T3.customer_key, T1.X1, T1.X2
from (select t1.*
from T1
where T1.X3 = '2018-02-01'
) t1 full outer join
(select t2.*
from T2
where T2.A3 = '2018-02-17'
) t2
on T1.Customer_key = T2.customer_key ;
Your filter turns the outer join into an inner join. Moving the conditions to the on clause returns all rows in both tables -- but generally with lots of null values. Using (T1.X3 = '2018-02-01' or t1.X3 is null) and (T2.A3 = '2018-02-17' or T2.A3 is null) doesn't quite do the right thing either. Filtering first is what you are looking for.
When you join tables via FULL OUTER JOIN, the query engine finds all matched records (INNER JOIN) and also add any unmatched records from both tables to the JOIN result set. The latter have NULLs in all columns for the other table.
So for example, customer = 1000 in T1 will be included in the JOIN result although there is no such customer in T2 but all columns from T2 will be NULL (because of FULL OUTER). Then, when you apply a WHERE clause on these records (WHERE is executed after JOIN operations) your result set will EXCLUDE customer = 1000 because T2.A3 = '2018-02-17' will fail (because T2.A3 is NULL for customer = 100).
I couldn't provide a query to your question because your explanation is lacking what you are trying to accomplish and I couldn't make sense of your result set: why customer = 1000 included but not customer = 1002 for example. Please describe what you're trying to accomplish.
Depending on what you're trying to accomplish, you can move part of your WHERE clause to JOIN or use filters like T1.customer is NULL / T1.customer is NOT NULL to identify cases where records didn't match / did match and filter exactly what you need.

group by id and random sample by id from two tables in big query sql

I have a 2 tables with the same structure:
table1
id text var
1 "bla bla" 100
1 "blabla1" 30
2 "qweweqty" 0
2 etc...
7
3
3
1
..
100
table2
id text var
101 "bla bla" 10
101 "bla1" 60
101 "bla" 5
103 etc...
102
103
102
110
..
200
I want to randomly sample data from table1 and table2 based on id. so basically, sample every observation for a random sample of ids from table1 and and every observation from random sample of ids from table2 so that 50 ids are from table 1 and 50 are from table 2 . any idea on how to do this on big query SQL?
en example would be the following where I want to get 3 ids from table1 and 3 from table2
randomly ids 1,2,3 are selected from table1, ids 101, 110 and 103 are selected from table2
the resulting table is then:
id. text var
1. .. ..
1
2
2
3
3
1
101
101
101
103
103
110
so basically any observation from table1 with id 1,2,3 and any observation from table2 with id 101, 103, 110 are selected and put in the same table:
so the passages are two: first randomly select a certain number of ids from table1, and a certain number of ids from table2, then I select any observation corresponding to those ids from both tables and I join them in the same table
If you want 50 ids from each table, then you can limit them using subqueries:
select t1.*
from t1 join
(select distinct id
from t1
order by rand()
limit 50
) ids
on t1.id = ids.id
union all
select t2.*
from t2 join
(select distinct id
from t2
order by rand()
limit 50
) ids
on t2.id = ids.id

Replacing null values with join

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.

Updating column in a table from another table using join

I have a two tables i need to copy from table 2 to table 1.
I want the table 1. column departure to be updated on the matching in table 2.
Condition
The table 2 have multiple items for the table 1,( table 1 have many relation with table 2). So in that case i need to sort it by RotationOrder and takes first row.
Table 1
Id Code Departure
479 JJ1256 NULL
480 SR1255 NULL
481 PFOBLEM NULL
482 SO1301 NULL
483 TS1302 NULL
484 YB1305 NULL
485 CU1303 NULL
Table 2
Id Departure RotationOrder CanLoad
479 NULL 1 1
480 NULL 1 2 1
481 NULL 1 3 1
482 NULL 1 4
482 NULL 3
482 NULL 2
482 NULL 4
483 2013-01-21 1 1
483 NULL 3
483 NULL 4
483 NULL 6
What i have tried
UPDATE table1 set Departure = (select top 1 table2.Departure from table2
INNER JOIN table1 on table1.Id = table2.Id where CanLoad =1 order by
RotationOrder )
FROM TABLE1 INNER JOIN TABLE2
ON TABLE1.Id = TABLE2.Id
Problem
This query copy first null value from the table2 and paste it on table1. which is incorrect.
Cross apply top 1, beloved classic:
UPDATE t1 set Departure = q.Departure
FROM table1 t1
cross apply
(
SELECT TOP 1 Departure
FROM table2
WHERE t1.Id=table2.Id
ORDER BY RotationOrder asc
)q
This is the way you'll want to do it:
UPDATE T1
SET Departure = T2.Departure
FROM Table1 T1
CROSS APPLY (SELECT ca.*
FROM Table2 ca
WHERE T1.Id = ca.Id
ORDER BY ca.RotationOrder) T2;
Notice the use of the table's alias in the UPDATE clause. If you use the table's actual name (not it's alias) you are technically declaring a 2nd Table1, which can/does produce odd behavior as it technically creates Cartesian product. It's therefore very important to use the syntax UPDATE [Table Alias] when using the FROM clause in an UPDATE statement.
Ignore null value rows. This assumes you have one non null row per Id
UPDATE Table1 set Departure = Table2.departure
FROM TABLE1 INNER JOIN TABLE2
ON TABLE1.Id = TABLE2.Id where Table2.canload =1 and Table2.deprture is not null

Getting the not matched rows from tbl_customer when left join with tbl_Linked table

I have two tables:
tbl_Customer
CustID Name Industry
101 a 2
102 b 1
103 c 2
104 d 2
tbl_linked :
Cust1 Cust2 Industry
101 103 2
For customerID 101 based on Industry (id=2) I get linked customer directly from
tbl_Linked is 103
if I want matched customer for CustID 101, then there are two matching on Industry = 2, they are 103 and 104. However since 103 is already linked in the link table i.e. tbl_Linked, then I should get matched as 104 only.
Hope this helps in understanding my problem, else pls let me know.
To get matched, I used joins *left join, but it is still giving me either 103 & 104 or none.
I want to get all matched first, then check in link table if any of them already linked, and filter those out and need rest as matched.
You could try something like this.
SELECT t2.CUSTID
FROM tbl_Customer t1
INNER JOIN tbl_Customer t2
ON (t1.Industry = t2.Industry)
LEFT OUTER JOIN tbl_linked t3
ON (t1.CUSTID = t3.Cust1 AND t2.CUSTID = t3.Cust2 AND t1.Industry = t3.Industry)
WHERE t1.CustID <> t2.CustID
AND t1.CustID = 101
AND t3.Cust2 IS NULL