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
Related
I'm looking to do what I believe is a double-nested check across three tables, but have no idea how to do so.
I have Table1, Table2, and Table3.
All are tied by an ID and a "Longform" and "Shortform" in Table1:
I'm trying to find:
Entries whose IDs appear in Table2 that have the same Longform as those in Table3, but don't share the same Shortform.
This is about as far as I've gotten:
SELECT T2.Longform,T2.Shortform FROM(
SELECT Table1.Longform,Table1.Shortform,Table1.ID FROM OuterTable1.Table1
LEFT JOIN OuterTable2.Table2 on Table1.ID = Table2.ID)
WHERE Table2.ID IS NOT NULL) T2
;
I know I'm probably going to have to do another nested select, or a join, on Outertable3.Table3 but I'm not sure which... Or where...
Any help appreciated as always.
Try the following:
Select *
(
Select T1.*
from T2
inner join T1
on T1.ID = T2.ID
) as Tab
inner join
(
Select T1.*
from T3
inner join T1
on T1.ID = T3.ID
) as Tab2
on Tab.id = Tab2.id
and Tab.Longform = Tab2.Longform
and Tab.Shortform <> Tab2.Shortform
To get the longform join table1 to table2 or table3. Then use EXISTS to check in a subquery if the IDs of table1 are different but the longform is equal.
SELECT *
FROM table2 t21
INNER JOIN table1 t11
ON t11.id = t21.id
WHERE EXISTS (SELECT *
FROM table3 t32
INNER JOIN table1 t12
ON t12.id = t32.id
WHERE t12.id <> t11.id
AND t12.longform = t11.longform);
Assuming ID is unique in all three tables
Select t2.id,t2.shortform, t1.shortform AS shortformTab1, t2.longform
FROM table2 t2
JOIN table3 t3
ON t2.id = t3.id AND t2.longform = t3.longform
JOIN table1 t1
ON t2.id = t1.id AND t2.shortform != t1.shortform
I have two tables Tables1 with ID, name, and Table2 has ID1, ID2, and ID3, name1, name2, and name3.
I want to select table1.ID not exists in tables2: ID1, ID2, and ID3
select T1.ID,t1.name
from table1 t1
where not exists (
SELECT *
FROM table2 t2
where t1.ID=t2.ID1 or t1.ID=t2.ID2 or or t1.ID=t2.ID3 )
I get error message for this query
After a little research, I could find this. Basically, you can't have multiple columns for a subquery in a IN or a NOT IN condition in the WHERE clause. This is why your query is currently failing : Your subquery get all the columns from Table2.
From my understanding of your question, you want a select where the results would be the elements that are not existing in Table2.
To do this, you can simply use a LEFT OUTER JOIN. In SQL, I would left join on all three columns, but it seems like Hive does not support multiple conditions in JOIN statements, so you can use the following alternative :
SELECT T1.ID, T1.name
FROM Table1 T1
LEFT JOIN Table2 T2_1 ON T2_1.ID1 = T1.ID
LEFT JOIN Table2 T2_2 ON T2_2.ID2 = T1.ID
WHERE (T2_1.id IS NULL) AND -- the id of Table2 - T2_1
(T2_2.id IS NULL) -- the id of Table2 - T2_2
Just add as many LEFT JOIN and conditions in the WHERE clause as you have columns to check.
Here's a fiddle with this query concept (the data are not the same, but the concept is).
Join first by ID1, then resulted dataset join by ID2, then resulted dataset join by ID3:
select p2.ID, p2.name --pass3
from
(select p1.ID, p1.name --pass2
from
(SELECT T1.ID, T1.name --pass1
FROM Table1 T1
LEFT JOIN Table2 T2 ON T2.ID1 = T1.ID
where T2.ID1 is null --not in ID1
) p1 LEFT JOIN Table2 T2 ON T2.ID2 = p1.ID
where T2.ID1 is null --also not in ID2
) p2 LEFT JOIN Table2 T2 ON T2.ID3 = p2.ID
where T2.ID1 is null --also not in ID3
Joins on 2 and 3 steps will receive already reduced dataset from T1 and this solution may be good for big tables.
SELECT DISTINCT ID,NAME
FROM
(SELECT T1.ID, T1.name
FROM Table1 T1
LEFT OUTER JOIN Table2 T2 ON T2.ID1 = T1.ID
where T2.ID1 is null
union
SELECT T1.ID, T1.name
FROM Table1 T1
LEFT OUTER JOIN Table2 T2 ON T2.ID2 = T1.ID
where T2.ID2 is null
union
SELECT T1.ID, T1.name
FROM Table1 T1
LEFT OUTER JOIN Table2 T2 ON T2.ID3 = T1.ID
where T2.ID3 is null)JO
I have some set of records, but now i have to select only those records from this set which have theeir Id in either of the two tables.
Suppose I have table1 which contains
Id Name
----------
1 Name1
2 Name2
Now I need to select only those records from table one
which have either their id in table2 or in table3
I was trying to apply or operator witin inner join like:
select *
from table1
inner join table2 on table2.id = table1.id or
inner join table3 on table3.id = table1.id.
Is it possible? What is the best method to approach this? Actually I am also not able to use
if exist(select 1 from table2 where id=table1.id) then select from table1
Could someone help me to get over this?
Use left join and then check if at least one of the joins has found a relation
select t1.*
from table1 t1
left join table2 t2 on t2.id = t1.id
left join table3 t3 on t3.id = t1.id
where t2.id is not null
or t3.is is not null
I would be inclined to use exists:
select t1.*
from table1 t1
where exists (select 1 from table2 t2 where t2.id = t1.id) or
exists (select 1 from table3 t3 where t3.id = t1.id) ;
The advantage to using exists (or in) over a join involves duplicate rows. If table2 or table3 have multiple rows for a given id, then a version using join will produce multiple rows in the result set.
I think the most efficient way is to use UNION on table2 and table3 and join to it :
SELECT t1.*
FROM table1 t1
INNER JOIN(SELECT id FROM Table2
UNION
SELECT id FROM Table3) s
ON(t.id = s.id)
Alternatively, you can use below SQL as well:
SELECT *
FROM dbo.Table1
WHERE id Table1.IN ( SELECT table2.id
FROM dbo.table2 )
OR Table1.id IN ( SELECT table3.id
FROM Table3 )
I want to use the result of a FULL OUTER JOIN as a table to FULL OUTER JOIN on another table. What is the syntax that I should be using?
For eg: T1, T2, T3 are my tables with columns id, name. I need something like:
T1 FULL OUTER JOIN T2 on T1.id = T2.id ==> Let this be named X
X FULL OUTER JOIN T3 on X.id = t3.id
I want this to be achieved so that in the final ON clause, I want the T3.id to match either T1.id or T2.id. Any alternative way to do this is also OK.
SELECT COALESCE(X.id,t3.id) AS id, *-- specific columns here instead of the *
FROM
(
SELECT COALESCE(t1.id,t2.id) AS id, * -- specific columns here instead of the *
FROM T1 FULL OUTER JOIN T2 on T1.id = T2.id
) AS X
FULL OUTER JOIN T3 on X.id = t3.id
Often, chains of full outer joins don't behave quite as expected. One replacements uses left join. This works best when a table has all the ids you need. But you can also construct that:
from (select id from t1 union
select id from t2 union
select id from t3
) ids left join
t1
on ids.id = t1.id left join
t2
on ids.id = t2.id left join
t3
on ids.id = t3.id
Note that the first subquery can often be replaced by a table. If you have such a table, you can select the matching rows in the where clause:
from ids left join
t1
on ids.id = t1.id left join
t2
on ids.id = t2.id left join
t3
on ids.id = t3.id
where t1.id is not null or t2.id is not null or t3.id is not null
You can do it like you suggested, using IN()
FROM T1
FULL OUTER JOIN T2
ON(T1.id = T2.id)
FULL OUTER JOIN T3
ON(T3.ID IN(T2.id,T1.id))
or I think you can do it with a UNION (depends on what you need) :
SELECT * FROM
(SELECT name,id from T1
UNION
SELECT name,id from T2) x
FULL OUTER JOIN T3
ON(t3.id = x.id)
I am trying to find the max date across multiple columns (in multiple tables). I have an SQL query that I think is almost workable, but am having a hard time debugging it. The problem is that it never returns anything. Any ideas on what I'm doing incorrectly? I don't get any errors, just an empty row "maxdate."
Here's my query:
SELECT
(
SELECT MAX(dates) FROM
(
SELECT dates = t1.UpdateDate
UNION ALL
SELECT dates = t2.UpdateDate
UNION ALL
SELECT dates = t3.UpdateDate
UNION ALL
SELECT dates = t4.UpdateDate
) as dateAcrossColumns
) as maxdate
FROM table1 as t1
join table2 as t2 on t1.ID = t2.ID
join table3 as t3 on t1.ID = t3.ID
join table4 as t4 on t1.ID = t4.ID
join table5 as t5 on t1.Status = t5.Status
WHERE t1.id = #param and t5.status <> 3
First join you join to table 2 using table 1's ID and table 3's ID. I presume you mean table 1's ID and table 2's ID?
join table2 as t2 on t1.ID = t3.ID
Should be:
join table2 as t2 on t1.ID = t2.ID
Now that this has been changed;
I tried your query and it works fine, are you sure that your joins are bringing back any rows? To test it replace your SELECT statement with SELECT *, if you get no rows back then they are being filtered out somewhere in your joins / WHERE.
If it's possible for any of the tables to not have any rows for the given #param, the (inner) joins will filter out all of the other tables.
Try unioning the dates and get the max of the unions
WITH allDates AS (
SELECT UpdateDate
FROM Table1
WHERE ID = #param
UNION
SELECT UpdateDate
FROM Table2
WHERE ID = #param
UNION
SELECT UpdateDate
FROM Table3
WHERE ID = #param
UNION
SELECT UpdateDate
FROM Table4
WHERE ID = #param
UNION
SELECT t5.UpdateDate
FROM Table5 AS t5
JOIN Table1 AS t1
ON t5.Status = t1.Status
WHERE t1.ID = #param
)
SELECT MAX( UpdateDate ) AS MaxDate
FROM allDates
Cant think of a simpler way of doing this :)
SELECT MAX(Dates) AS RequiredDate
FROM (
SELECT t1.UpdateDate AS DateOne
,t2.UpdateDate AS DateTwo
,t3.UpdateDate AS DateThree
,t4.UpdateDate AS DateFour
FROM table1 as t1
join table2 as t2 on t1.ID = t2.ID
join table3 as t3 on t1.ID = t3.ID
join table4 as t4 on t1.ID = t4.ID
join table5 as t5 on t1.[Status] = t5.[Status]
WHERE t1.id = #param and t5.[Status] <> 3
)t
UNPIVOT (Dates FOR DateCols
IN (DateOne, DateTwo,DateThree,DateFour))up
I was trying to solve a similar problem to find the last modified date across a set of joined tables in MySQL. The following worked for me using a combination of GREATEST and MAX:
SELECT GREATEST(MAX(t1.modified), MAX(t2.modified), MAX(t3.modified),
MAX(t4.modified)) AS lastmodified
FROM `table1` AS t1
LEFT JOIN `table2` AS t2 ON t1.id = t2.t1_id
LEFT JOIN `table3` AS t3 ON t2.id = t3.t2_id
LEFT JOIN `table4` AS t4 ON t3.id = t4.t3_id
WHERE t1.id = #param