Using update with Left Join and cross join BigQuery - google-bigquery

I have a followup question on my already posted question.
Using update with Left Join BigQuery
I amt trying to achieve the same result but also adding Cross Join in it.
update Table1
set ColumnTest = ifnull(b.value, 'no run')
From left join
(select distinct h.eventinfo.eventcategory as ID,value
FROM Table2
cross join (hits)h )
where Table1.ID= Table2.ID
I have 2 tables Table1 and Table2
I want to update Table1.ColumnTest with Table2.Value
where Table1.ID= Table2.hits.eventInfo.eventCategory (Unnest Table2)
and if Table1.ID <> Table2.hits.eventInfo.eventCategory then update Table1.ColumnTest with 'no run'
Thanks for you help!!

Try below
UPDATE `table1` t1
SET ColumnTest = IFNULL(t2.value, 'no run')
FROM (
SELECT id, value
FROM `table1`
LEFT JOIN (
SELECT hit.eventInfo.eventCategory AS id, value
FROM `table2`
CROSS JOIN UNNEST (hits) AS hit
)
USING(id)
) t2
WHERE t1.ID = t2.ID

Related

Using update with Left Join BigQuery

I am trying to write an Update query with LEFT JOIN in BigQuery but I am not sure how to write it.
update Table1
set ColumnTest = ifnull(b.value, 'no run')
From left join (select distinct ID,value FROM Table2 where value = 10) B --
where Table1.ID= Table2.ID
I have 2 tables Table1 and Table2
I want to update Table1.ColumnTest with Table2.Value where Table1.ID= Table2.ID
and if Table1 <> Table2 then update Table1.ColumnTest with 'no run'
Thanks!!
New Try
UPDATE Table1
SET LP = IFNULL(t2.value, 'no run')
FROM ( select distinct hits.eventInfo.eventCategory as ID, value
FROM Table2
CROSS JOIN UNNEST (hits) AS hits
left join TAble1 using (hits.eventInfo.eventCategory)
WHERE) t2
WHERE t1.ID = t2.ID
Error: Syntax error: Expected ")" or "," but got "."
I want to update Table1.ColumnTest with Table2.Value where Table1.ID= Table2.ID and if Table1 <> Table2 then update Table1.ColumnTest with 'no run'
Below is for BigQuery Standard SQL
UPDATE `table1` t1
SET ColumnTest = IFNULL(value, 'no run')
FROM (
SELECT id, value
FROM `table1`
LEFT JOIN `table2`
USING(id)
) t2
WHERE t1.id = t2.id

sql union displays duplicates

image of what I want
I have tried the join on x or y and it didn't work, even the group by didn't work.
What almost gave me the result is the query below
SELECT A.Id ,A.AccNo ,A.Name ,B.Id ,B.AccNo1 ,B.AccNo2 ,B.Name
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo1
union
SELECT A.Id ,A.AccNo ,A.Name ,B.Id, B.AccNo1, B.AccNo2, B.Name,
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo2
After getting the query correct I want to show only the exceptions where there was no link between the tables and its kind of difficult if the T1.ID is repeated
You seem to want a left join:
select t1.*, t2.*
from table1 t1 left join
table2 t2
on t1.id in (t2.accno1, t2.accno2);
Try:
SELECT A.Id ,A.AccNo ,A.Name ,B.Id ,B.AccNo1 ,B.AccNo2 ,B.Name
from Table1 as A
left outer join Table2 as B
ON A.AccNo = (CASE WHEN A.AccNo = B.AccNo1 THEN B.AccNo1 ELSE B.AccNo2 END)
You may nest your original query, and then use max aggregate function with grouping :
SELECT Id ,AccNo ,Name, max(Id2) as Id2, max(Name2) as Name2,
max(AccNo1) as AccNo1, max(AccNo2) as AccNo2
FROM
(
SELECT A.Id ,A.AccNo ,A.Name ,B.Id Id2 ,B.AccNo1 ,B.AccNo2 ,B.Name Name2
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo1
union
SELECT A.Id ,A.AccNo ,A.Name ,B.Id Id2, B.AccNo1, B.AccNo2, B.Name Name2
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo2
) q
GROUP BY Id ,AccNo ,Name;
SQL Fiddle Demo
Do a LEFT JOIN to return the table1 values along with matching table2 values (where t2.accno2 = t1.accno):
select t1.*, t2.*
from table1 t1
left join table2 t2
on t1.accno = t2.accno2
Or, perhaps you want table2 values for matching accno1's as well?
select t1.*, t2.*
from table1 t1
left join table2 t2
on t1.accno in (t2.accno1, t2.accno2)
It this way to resolve:
SELECT
t1.id,
t1.accno,
t1.name,
(
SELECT DISTINCT
id
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
name
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
accno1
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
accno2
FROM
table2
WHERE
accno2 = t1.accno
) FROM
table1 t1
LEFT JOIN table2 t2 ON t1.accno = t2.accno1 OR t1.id = t2.id

Convert to join query

select t.* from table1 t where t.id NOT IN(
select Id from t2 where usrId in
(select usrId from t3 where sId=value));
I the result i need is like if there are matching id's in t1 and t2 then those id's should be omitted and only the remaining rows should be given to me. I tried converting into join but it is giving me the result i wanted. Below is my join query.
SELECT t.* FROM table1 t JOIN table2 t2 ON t.Id <> t2.Id
JOIN table3 t3 ON t3.Id=t2.Id WHERE t3.sId= :value
This doesn't feth me the correct result. it was returning all the rows, but i want to restrict the result based on the matching id's in table t1 and table t2. Matching id's should be ommited from the result.I will be passing the value for sId.
I believe this to be an accurate refactor of your query using joins. I don't know if we can do away with the subquery, but in any case the logic appears to be the same.
select t1.*
from table1 t1
left join
(
select t2.Id
from table2 t2
inner join table3 t3
on t2.usrId = t3.usrId
where t3.sId = <value>
) t2
on t1.Id = t2.Id
where t2.Id is null
Let's break down and solve problem step by step.
So your query
select t.* from table1 t where t.id NOT IN(
select Id from t2 where usrId in
(select usrId from t3 where sId=value));
on converting the inner query to JOIN will yield
select t.* from table1 t where t.id NOT IN
(SELECT T2.ID FROM T2 JOIN T3 on T2.UsrID =T3.UsrID and T3.sID=value)
which on further converting to JOIN with outer table will be
select t.* from table1 t LEFT JOIN
(SELECT T2.ID FROM T2 JOIN T3 on T2.UsrID =T3.UsrID and T3.sID=value)t4
ON t.id =T4.ID
WHERE t4.ID is NULL
In case you completely want to remove sub-query you can try like this
SELECT t.*
FROM table1 t
LEFT JOIN T2
ON T.ID=T2.ID
LEFT JOIN T3
ON T3.UsrId=T2.UsrID AND T3.sId=value
WHERE T3.UsrID IS NULL

SQL Joins using NULL

I want to join the two tables above to show the appropriate Authorizationcode based on the NameID.
If the NameID matches, then will show corresponding Authorizationcode,
If it does not, then it will show the other Authorizationcode
NameID and OrderID are uniqueidentifiers.
The result should be:
cyclophosphamide - Auth01234
Adriamycin RDF - Auth01234
Neulasta - Auth04567
Not able to join based on NULL NameID. Please suggest.
This is a bit tricky. Here is a method that uses two left joins. The condition on the second one only chooses the NULL row from table2 (a cross join could also be used):
select t1.name, coalesce(t2.authorizationcode, t2null.authorizationcode) as authorizationcode
from table1 t1 left join
table2 t2
on t1.nameid = t2.nameid left join
table2 t2null
on t2null.nameid is null;
This is ANSI standard and should work in most databases.
I would approach this with a UNION
SELECT DISTINCT NameID, AuthorisationCode
FROM
( SELECT NameID, AutorisationCode
FROM table1 t1 INNER JOIN
table2 t2 ON t1.nameid = t2.nameID
UNION
SELECT NameID, AutorisationCode
FROM table1 t1 LEFT OUTER JOIN
table2 t2 ON t1.nameid = t2.nameID
) DATA
Try this one:
SELECT t1.Name, ISNULL(t2.AuthorizationCode, t3.AuthorizationCode) AS AuthorizationCode
FROM Table1 AS t1
LEFT JOIN Table2 AS t2 on t1.NameID = t2.NameID AND t1.OrderID = t2.OrderID
LEFT JOIN Table2 AS t3 on t3.NameID IS NULL AND t1.OrderID = t3.OrderID
I assume you also want to join on OrderID. If not please make your question more clear.
Your screenshots are from management studio so a SQL Server specific answer.
SELECT t2.Name, CA.AuthorizationCode
FROM Table2 t2
CROSS APPLY
(
SELECT TOP (1) *
FROM Table1 t1
WHERE t1.OrderId = t2.OrderId
AND (t1.NameId = t2.NameId OR t1.NameId IS NULL)
ORDER BY t1.NameId DESC -- not null prioritised over null
) CA
It would need an index on table1 (OrderId, NameId)

Transform select count(*) inside a inner join

My problem here is that i'm modifying an existing query and i cannot use count(*) in the query.
I have to use inner join subqueries.
What i need to "transform" into my inner join is like this (this works):
SELECT count(distinct t1.id)
FROM table1 t1
WHERE t1.column1 = 'value1' AND
t2.column2 = 'value2' AND
EXISTS(select 1 from table2 t2 where t2.id = t1.id)
My global query looks like this:
SELECT [many many column]
FROM table2 t2
INNER JOIN [...]
LEFT OUTER JOIN [...]
--[I NEED MY COUNT HERE, see below for example]
WHERE [some conditions are true]
ORDER BY [some column]
What i found to help me is something like this:
SELECT [many many column], myJoin.Count
FROM table2 t2
INNER JOIN (
SELECT tt2.id, count(distinct tt2.id) as Count
FROM table2 tt2
WHERE EXISTS (SELECT 1 FROM table1 tt1 where tt1.id = tt2.id)
GROUP BY tt2.id) myJoin
on t2.id = myJoin.id;
See what i'm trying to acheive? I need to count the ids, joining 2 tables, but i can't have a count in my main query, i can't possibly copy-paste all the "group by" condition that would go with it...
I'm on sql server.
If i find the answer i will come back and post it.
Thanks for any advice/tricks about this.
How about the following:
SELECT table2.*, TopQ.MyCount
FROM (
SELECT t2.id, myJoin.MyCount
FROM table2 t2
INNER JOIN (
SELECT tt2.id, count(distinct tt2.id) as MyCount
FROM table2 tt2
WHERE EXISTS
(SELECT 1 FROM table1 tt1 where tt1.id = tt2.id)
GROUP BY tt2.id) AS myJoin
on t2.id = myJoin.id
)AS TopQ
INNER JOIN table2 ON TopQ.id = table2.id
I came across this:
select count(distinct t1.id) over (partition by t1.aColumn) as myCount,
[many many column]
from table2 t2
inner join table1 t1 on [someConditions] = value1 and
[someConditions] = value2 and
t2.id = t1.id;
I get the same results as my first select i posted in my question, and without adding a "group by" anywhere and a lot of inner join that im not that familliar with. I'm gonna stick with this solution.
Thanks!