Using Case statement in Where clause - sql

In my query I have the following condition
left Join Table2 on Table2.Id = Table1.Id and Table2.status in ('Close', 'Open')
And the above condition gives me 2 extra rows because of the left join. I noticed that if I have only either Close or Open in the condition it returns the correct number of rows.
To fix that I was trying to write something like this
And Table2.status = (Case Table2.status
WHEN 'Open' Then 'Open'
When 'Close' Then 'Close'
End )
But this still returns 2 extra rows. Any suggestions on how to fix this??

You could do something like this:
select *
from table1
left join
(
select id from table2
where status in ('open', 'close')
group by id
) as table2
on table1.id = table2.id
This seems pretty hacky, but I cannot seem to come up with something better at the moment. Otherwise, you could use a DISTINCT
select DISTINCT table1.*, table2.stuff
FROM Table1
LEFT JOIN Table2
on Table2.Id = Table1.Id and Table2.status in ('Close', 'Open')

The key is the DISTINCT statement.
SELECT DISTINCT Table1.* FROM Table1
LEFT JOIN Table2 ON Table2.Id = Table1.Id
AND Table2.status in ('Close', 'Open')

Related

subquery in SELECT without JOIN in Hive?

I know Hive doesn't support this
SELECT (CASE WHEN table1.id in (SELECT table1.id
from table1,table2
where table1.id = table2.id and table2.company like '%My Company%')
THEN table1.email
ELSE regexp_replace(table1.email, substr(table1.email, 1), 'XXXX')
END) as email, table1.id
FROM table1
Hive cannot do SELECT within SELECT (subquery in SELECT).
But let say for some restriction I cannot do JOIN after FROM clause. Is there a "creative" way to do this? I was thinking about parsing and passing a "static list" from SELECT table1.id from table1,table2 where table1.id = table2.id and table2.company like '%My Company%' in a separate query. But this could go up to thousands.
if you could use a select for a join the you could use a left join and check for null value
SELECT case when t1.id is null
then regexp_replace(table1.email, substr(table1.email, 1), 'XXXX')
else table1.email
end
, table1.id
FROM table1
left join (
SELECT table1.id
from table1,table2
where table1.id = table2.id
and table2.company like '%My Company%'
) t on table1.id = t.id

Need help in sql query to give result set based on previous version

i have two tables , table1 and table2.
table1
id name city uqid
1 vikas mysore 2
table2
id uqid name status
1 1 vikas pending
1 2 Vikas processing
I have a SQL query to fetch the details of table1 joined with table2
select table1.id,
table1.name,
table1.city,
table2.status
from table1
left outer join table2
on table2.uqid = table1.uqid
and table2.id = table1.id
this will give me the result set
id name city status
1 vikas mysore processing
how can i modify the above query to not to give us the result set until the status is set to "pass" in table2 for uqid = 1 and id = 1 ?
Try the following.
select table1.id,
table1.name,
table1.city,
table2.status
from table1
left outer join table2
on table2.uqid = table1.uqid
and table2.id = table1.id
where table2.status ilike 'pass';
If by stating that you need table2's uqid=id=1, you mean that you need both the fields to have same value then use the following.
select table1.id,
table1.name,
table1.city,
table2.status
from table1
left outer join table2
on table2.uqid = table1.uqid
and table2.id = table1.id
where table2.status ilike 'pass' and table2.uqid=table2.id;
Suggestion: Try to normalize your tables
I am not sure this is the proper way or any other efficient way exists , but this will give you the desired result.
select table1.id,
table1.name,
table1.city,
table2.status
from table1
left outer join table2
on table2.uqid = table1.uqid and table2.id = table1.id
where table1.id in(select distinct id from table2 where status like 'pass'
and uqid not in(select uqid from table1))

MySQL join on record that might not exist

I'm trying to execute a query that looks similar to this:
SELECT <columns> FROM table1
INNER JOIN table2 ON table1.id = table2.table1_id
INNER JOIN table3 ON table1.id = table3.table1_id
WHERE table3.column1 != 'foo' AND <other_conditions>
LIMIT 1;
The thing is--I want the query to return a result regardless of whether the record in table3 exists or not. That is--if the record in table3 is present, I want to check whether that record has a certain column value. If the record in table3 doesn't exist, I want the query to assume that the condition is TRUE.
Any pointers?
You use a left join on the table. If no corresponding record exists, the value from the table will be null, so you can use coalesce to get a value that you can compare to the string:
SELECT <columns> FROM table1
INNER JOIN table2 ON table1.id = table2.table1_id
LEFT JOIN table3 ON table1.id = table3.table1_id
WHERE COALESCE(table3.column1, '') != 'foo' AND <other_conditions>
LIMIT 1
You've come to a point where you noticed that there is a difference between WHERE conditions and JOIN conditions.
SELECT
<columns>
FROM
table1
INNER JOIN table2 ON table2.table1_id = table1.id
LEFT JOIN table3 ON table3.table1_id = table1.id AND table3.column1 <> 'foo'
WHERE
<other_conditions>
LIMIT 1;
You need to use an outer join to include table3 instead of an inner join.

Subquery not in performance question

I have this slow query
select * from table1 where id NOT IN ( select id from table2 )
Would this be faster by doing something like (not sure if this is possible):
select * from table1 where id not in ( select id from table2 where id = table1.id )
Or:
select * from table1 where table1.id NOT EXIST( select id from table2 where table2.id = table1.id )
Or:
select * from table1
left join table2 on table2.id = table1.id
WHERE table2.id is null
Or do something else? Like break it up into two queries ...
The question is - are the field(s) in the comparison nullable (meaning, can the column value be NULL)?
If they're nullable...
...in MySQL the NOT IN or NOT EXISTS perform better - see this link.
If they are NOT nullable...
... LEFT JOIN / IS NULL performs better - see this link.
select table1.* from table1
LEFT JOIN table2 ON table1.id = table2.id
WHERE table2.id IS NULL
The object being to get rid of NOT IN

Selecting records based on two other tables

I have a query with inner join to another table, with this I want also include records which are contained in another column.
Example:
select name, address from table1
inner join table2 on table1.id = table2.id
With this, I want to also include rows which are having table1.recno = (1,2,4).
How could I write query for that?
One option I know is to use the IN keyword instead of the first table join. But our client doesn't want to use the IN keyword.
Use a left join and then use the WHERE clause to filter out the rows that you need.
select name, address
from table1
left join table2 on table1.id = table2.id
where
table2.id IS NOT NULL OR table1.ID In (1,2,4)
Or if you want to avoid an innocuous IN for silly reasons, use:
select name, address
from table1
left join table2 on table1.id = table2.id
where
table2.id IS NOT NULL
OR table1.ID = 1
OR table1.ID = 2
OR table1.ID = 4