I have two tables: table1 and table2 both with one column for ID. I want to create a column in table1 that displays 'Y' if ID in table1 is in table2 and 'N' if it is not.
Currently, I am using:
Select id, case when id in (table2) then 'Y' else 'N' end as in_table2
from table1
However, since both tables are very big, the query is taking forever. Is there a more efficient way of doing this?
Thanks
Use exists:
Select t1.id,
(case when exists (select 1 from table2 t2 where t2.id = t1.id)
then 'Y' else 'N'
end) as in_table2
from table1 t1;
This should be much quicker and efficient than using exists/subqueries:
SELECT t1.id ,
CASE WHEN t2.id IS NULL
THEN 'N'
ELSE 'Y'
END AS in_table2
FROM table1 t1
LEFT JOIN TABLE2 t2 ON t1.id = t2.id;
By left joining you maintain visibility of the records on table2, and if the ID is null, you know it exists on table1 but not on table2, so you can safely use a case statement to show Y or N based on t2.id.
Related
I have two tables:
Table 1
Table 2
I am trying to write a query to SELECT all records for both tables, using UNION (columns ID, Date and Amount). The tables are linked by ID. When selecting the records in Table 2 however during the UNION, if the related ID in Table 1 has a True or False value of TRUE, I want to change the Date of the Table 2 record to the date in Table 1, ultimate acheiving this:
Is this possible?
The 2nd query of UNION ALL should be a join of the tables:
select id, date, amount
from Table1
union all
select
t2.id,
case when t1.trueorfalse = 'TRUE' then t1.date else t2.date end
t2.amount
from Table2 t2 inner join Table1 t1
on t1.id = t2.id
The CASE expression will return either the date from Table1 or from Table2.
If your database supports the Boolean data type maybe you should use TRUE instead of 'TRUE'.
This seems like a convenient place to use a lateral join, if your database supports it:
select v.*
from table1 t1 join
table2 t2
on t1.id = t2.id cross join lateral
(values (t1.id, (case when t1.true_or_false = 'true' then t2.date else t1.date end), t1.amount),
(t2.id, t2.date, t2.amount)
) v(id, date, amount);
I am currently trying to obtain data from two tables that have the same columns. The values for primary key "ID" of both tables may exist in one or both tables. Even with same primary keys, the values in different columns may not be the same for both tables. My question is given I have an ID testID, how do I query where in I first check table1 if it exists. If it exists in table1 I use the details found in table1, otherwise check table2 and use details in table2 if it exists in table2.
Either use a FULL OUTER JOIN:
select
case when t1.id is not null then t1.field1 else t2.field1 end as field1,
case when t1.id is not null then t1.field2 else t2.field2 end as field2,
...
from table1 t1
full outer join table2 t2 on t2.id = t1.id
where t1.id = :testid or t2.id = :testid;
Or UNION ALL in combination with NOT EXISTS:
select field1, field2, ...
from table1
where id = :testid
union all
select field1, field2, ...
from table2
where id = :testid and not exists (select * from table1 where id = :testid);
The possible way is to use FULL OUTER JOIN
SELECT t1.id,
t2.id,
CASE
WHEN t1.id IS NOT NULL
AND t2.id IS NOT NULL
THEN 'ID in both sources'
WHEN t1.id IS NULL
THEN 'ID in T2 only'
WHEN t2.id IS NULL
THEN 'ID in T1 only'
END source_key
FROM t1
FULL OUTER JOIN t2
ON t1.id = t2.id
WHERE t1.id = 1 -- your test_id here
OR t2.id = 1; -- your test_id here
Cheching if T1.ID/ T2.ID is not NULL you get the information if the record is defined in the respective source table.
What I am trying to do can be exemplified (Incorrectly) by the following query
SELECT * FROM Table1
WHERE User IN
(CASE (SELECT Username From Table2 Where Table2.ID = 1)
WHEN IS NULL THEN NULL
ELSE (SELECT Username From Table2 Where Table2.ID = 1) END)
Since User = NULL is not the same as User IS NULL something with the above syntax won't work. Is there a way to do this? I don't want to grab NULLS if there are records in Table2.
For Example,
Table1
ID User
1 Elias
2 NULL
Table2
ID Username
1 Elias
2 NULL
I would want the above select to return the following recordset
ID User
1 Elias
If I was looking for ID 2 in Table 2 I would want the following recordset
ID User
2 NULL
If you want to consider two NULL values as matching, you can do:
select t1.*
from table1 t1
where exists (select 1
from table2 t2
where t1.user = t2.username or t1.user is null and t2.user is null
);
If you are trying to match values in table2 and if there are no values in table2 then return values equal to NULL (how I interpret the title):
select t1.*
from table1 t1
where exists (select 1
from table2 t2
where t1.user = t2.username or t1.user is null and t2.user is null
) or
(not exists (select 1 from table2) and t1.user is null);
EDIT:
For performance, you can do:
select t1.*
from table1 t1
where exists (select 1
from table2 t2
where t1.user = t2.username
) or
exists (select 1
from table2
where t1.user is null and t2.user is null
) or
(not exists (select 1 from table2) and t1.user is null);
These can take advantage of an index on table2(user).
A link where you use null as a relation between table will get you a wrong number of rows. Duplicated rows and stuff.
The simplest query I can think of (in order to avoid this) is:
select t1.*
from table1 t1
join table2 t2
on t1.user = t2.username
This will filter out the nulls.
In case that you also need to aggregate here null use Gordon's query, though if you have multiple nulls in one of the tables then your query is meaningless.
If u want to use IN clause
SELECT * FROM Table1
WHERE User IN
(SELECT isnull(Username,'') From Table2 Where 1 = 1)
I want to update a column of table based on a condition. It should check if the value exists in other table, if exists then value from other table will be used else value from same table will be used.
Update table1
Set column1=(select t2.alias||’#email.com’ as new_name
From table2 t2, table1 t1, table3 t3
Where t1.id=t2.id
And t1.id=t3.id
Else if
Select t2.alias is null or t2.id is null
then column1= select t1.id||’#email.com’ as new_name
Any suggestions on this??
Thanks in advance.
Does this do what you want?
Update table1
Set column1 = (select (case when t2.alias is not null and t2.id is not null then t2.alias
else t1.id
end) ||'#email.com' as new_name
From table1 t1 left outer join
table2 t2
on t1.id=t2.id
);
I removed table3 because it does not seem to be used. With left join is won't even be filtering any results.
By leaving out the "insert" half of the merge statement, you can make it into a strictly update statement:
MERGE INTO table1 t
USING(
SELECT t2.id, t2.Alias
FROM table2 t2
JOIN table1 t1
ON t1.id = t2.id
AND t1.Alias <> t2.Alias
) tu
on( tu.id = t.id )
WHEN MATCHED THEN
update set t.Alias = tu.Alias;
The query will return only those existing values from table2 that differ from table1. To make it exactly match your requirement (update table1 if any value exists in table2) then remove the line AND t1.Alias <> t2.Alias, but why update a field to the same value it already has?
I need to run a query where one of the fields returned is a yes or no if there is a row in another table matching one of the key fields in the first table.
Sounds like a job for join, except the second table is one to many and I just need to know if there are zero or a non zero number of rows in the secondary table.
I could do something like this:
select t1.name, t1.id, (select count(1) from t2 where t1.id=t2.id) from t1
but I'd like to avoid making an aggregate subquery if possible.
It was mentioned to me that I could use the exists() function, but I'm not seeing how to do that in a select field.
This is sybase 15 by the way.
You could still do the JOIN, something like this:
SELECT t1.name, t1.id, CASE WHEN t2.id IS NULL THEN 0 ELSE 1 END Existst2
FROM t1
LEFT JOIN (SELECT id FROM t2 GROUP BY id) t2
ON t1.id = t2.id
ahhh, I got it from another stackoverflow quetion...
case when exists (select * from t2 where t1.id = t2.id) then 1 else 0 end
I am just writing down the syntax here:
if exists (select * from table1 t1 inner join table1 t2 on t1.id = t2.id )
select * from table2
How about this query ( Work with all databases )
select t1.name, t1.id, 'Y' as HasChild
from t1
where exists ( select 1 from t2 where t2.id = t1.id)
UNION
select t1.name, t1.id, 'N' as HasChild
from t1
where NOT exists ( select 1 from t2 where t2.id = t1.id)