Oracle 11g, how to speed up an 'in' query - sql

I was trying to create a view and needed to create a column that shows if the 'somenumber' column exists on other table or not. The code below worked but very slowly. Is it possible to declare a table as (select someNumber from veryYugeTable) and check on that one instead of sending this query for every single record or using some other way to speed up the view?
case
when someOtherTable.someNumber in(select someNumber from veryYugeTable) then 'exists'
else 'doesn't exist'
end as "someColumn"

The query looks fine. You should have an index on veryYugeTable.someNumber.
Sometimes the optimizer handles correlated subqueries better than non-correlated ones, so you can try:
case
when exists
(
select *
from veryYugeTable
where veryYugeTable.someNumber = someOtherTable.someNumber
) then 'exists'
else 'doesn''t exist'
end as "someColumn"
(Well, as this query does exactly the same as yours, the optimizer should get to the same execution plan, but this is not always the case.)
But as mentioned: Make sure first to have that index.

You might find you get some benefit with scalar subquery caching if you do something like:
coalesce((select 'exists'
from veryyugetable vyt
where vyt.somenumber = someOtherTable.someNumber
and rownum = 1),
'doesn''t exist') somecolumn
N.B. the and rownum = 1 is not necessary if vyt.somenumber is a unique column. Also, I nth the suggest to index the vyt.somenumber column.

use left join instead of putting the in clause in select:
left join veryYugeTable on someNumber = someOtherTable.someNumber
adjust your case when statement as follow:
case
when veryYugeTable.OtherColumn is null then 'doesn''t exist'
else 'exist'
end as "someColumn"

Related

How to use subquery in caes statement

I want use select~~~~ subquery in case statement
but I Don't know how to do this
In my idea is
CASE When
(select ...from ... where .. )IS null
then ...
else ...
end as ...
but it's not working
You can do a temp table and query that
with
test as (select names from table where names=smith ) ---You can add in left
--joins here or whatever - again not sure what you are trying to accomplish
select Case when name=smith then "Yes" else Null end as Case_test
from test
Probably an easier way to do it with a subquery but off the top of my head I'm not sure. We would need more detail on what you were trying to accomplish but this would probably do the trick.

SELECT-CASE-IN-SELECT error: [SQL0115] Comparison operator IN not valid. In query db2

i have a problem in a db2 query
I tried run this query
SELECT t.* ,
CASE WHEN column in (SELECT data FROM otherTable WHERE conditions...)
then 5
else 0
end as 'My new data'
FROM table t
WHERE conditions....
But get error
[Error Code: -115, SQL State: 42601] [SQL0115] Comparison operator IN not valid.
When i change the sub-query to where statement like this
SELECT t.*
FROM table t
WHERE column in (SELECT data FROM otherTable WHERE conditions...)
Works fine
Why not work in the case statement? It is a limitation of db2?
And could make an equivalent behavior?
One way to do this is to left join to the table and check if it is not null.
In most cases this will be the fastest way because SQL servers are optimized to perform joins very quickly (but will depend on a number of factors including data model, indexes, data size, etc).
Like this:
SELECT t.* ,
CASE WHEN othertable.data is not null
then 5
else 0
end as 'My new data'
FROM table t
left join otherTable ON otherTable.column = data
WHERE conditions....
Try with using exists condition as below (put the column value in the where clause of subquery) :
SELECT t.* ,
CASE WHEN exists (SELECT data FROM otherTable WHERE conditions... and column=val)
then 5
else 0
end as 'My new data'
FROM table t
WHERE conditions....

Case clause execution procedure

Hi i have a SQL which is extremely slow.
select case when (value=1)
then (select <Some Math Logic> from table where table.id=table_2.id)
else 'false' end
from table_2 where <where clause>
what i want to know is how does the case clause work..??
the part select <Some Math Logic> from table is working on huge table set.
in Java we see that for an if statement
if(condition_1==true)
{return output;}
else
{return false;}
if the if statement is false then the part inside it is never processed, then what i want to know is if it is the same in the oracle SQL also.
does it work on the following logic..??
Check Case condition
if true, process inside output
else process other output.
or does it take the below logic:
pre-process all sub-queries
Check Case condition
if true, display inside output
else display other output.
please help
edit: Guys i dont want to tune the query shown above... this is just a dummy one.
what i need to know is how the case clause works step by step.
please share if any one has some input for that
Does this solve your problem?
SELECT
COALESCE(<Some Math Logic>, 'false')
FROM table_2 T2
LEFT JOIN table T
ON T.Id = T2.Id
and T2.value = 1
WHERE <where clause>
It seems that the logic is exactly like that in java.
I used the following logic to test your scenario:
I created a dummy function as below which will just write something on the dbms_output and return only 10.
CREATE OR REPLACE
FUNCTION DISP_MSG
RETURN VARCHAR2
AS
ret_val VARCHAR2(20):='10';
BEGIN
dbms_output.enable;
dbms_output.put_line('executed');
RETURN ret_val;
END DISP_MSG;
then i created an anonymous block to test the same:
DECLARE
var VARCHAR2(100);
BEGIN
SELECT CASE WHEN (1!=1) THEN DISP_MSG ELSE '1' END INTO var FROM dual;
dbms_output.put_line('j = '||var);
END;
Output:
j = 1
but when i tried the below:
DECLARE
var VARCHAR2(100);
BEGIN
SELECT CASE WHEN (1=1) THEN DISP_MSG ELSE '1' END INTO var FROM dual;
dbms_output.put_line('j = '||var);
END;
Output:
executed
j = 10
so its quite clear what is the execution logic
Good question. You need to see the execution plan to know for sure. The database engine is free to use any algorithm it sees fit so long as it gets you the results you asked for.
It could even outer join table to get the results in anticipation of value = 1. Or it could run the select from table and store the results into a temporary table that it can scan when it runs the main query.
Most likely, however, it is running the subquery for every row where value = 1. Hard to tell without seeing the plan.
It also depends on the details of . Are you taking aggregates? If so, a true join may be impossible and it may have to recalculate the answer for every row. If it's looking at values right on the table rows, then it may be able to optimize that away.
If you take the case statement out, does the overall query perform much faster? Want to make sure you are analyzing the correct sub-query.

How to select an empty result set?

Want to improve this post? Provide detailed answers to this question, including citations and an explanation of why your answer is correct. Answers without enough detail may be edited or deleted.
I'm using a stored procedure in MySQL, with a CASE statement.
In the ELSE clause of the CASE ( equivalent to default: ) I want to select and return an empty result set, thus avoiding to throw an SQL error by not handling the ELSE case, and instead return an empty result set as if a regular query would have returned no rows.
So far I've managed to do so using something like:
Select NULL From users Where False
But I have to name an existing table, like 'users' in this example.
It works, but I would prefer a way that doesn't break if eventually the table name used is renamed or dropped.
I've tried Select NULL Where False but it doesn't work.
Using Select NULL does not return an empty set, but one row with a column named NULL and with a NULL value.
There's a dummy-table in MySQL called 'dual', which you should be able to use.
select
1
from
dual
where
false
This will always give you an empty result.
This should work on most DBs, tested on Postgres and Netezza:
SELECT NULL LIMIT 0;
T-SQL (MSSQL):
SELECT Top 0 1;
How about
SELECT * FROM (SELECT 1) AS TBL WHERE 2=3
Checked in myphp, and it also works in sqlite and probably in any other db engine.
This will probably work across all databases.
SELECT * FROM (SELECT NULL AS col0) AS inner0 WHERE col0 IS NOT NULL;
SELECT TOP 0 * FROM [dbo].[TableName]
This is a reasonable approach to constant scan operator.
SELECT NULL WHERE FALSE;
it works in postgresql ,mysql, subquery in mysql.
How about this?
SELECT 'MyName' AS EmptyColumn
FROM dual
WHERE 'Me' = 'Funny'
SELECT * FROM (SELECT NULL) WHERE 0
In PostgreSQL a simple
SELECT;
works. You won't even get any columns labeled 'unknown'.
Note however, it still says 1 row retrieved.

Check whether a table contains rows or not sql server 2005

How to Check whether a table contains rows or not sql server 2005?
For what purpose?
Quickest for an IF would be IF EXISTS (SELECT * FROM Table)...
For a result set, SELECT TOP 1 1 FROM Table returns either zero or one rows
For exactly one row with a count (0 or non-zero), SELECT COUNT(*) FROM Table
Also, you can use exists
select case when exists (select 1 from table)
then 'contains rows'
else 'doesnt contain rows'
end
or to check if there are child rows for a particular record :
select * from Table t1
where exists(
select 1 from ChildTable t2
where t1.id = t2.parentid)
or in a procedure
if exists(select 1 from table)
begin
-- do stuff
end
Like Other said you can use something like that:
IF NOT EXISTS (SELECT 1 FROM Table)
BEGIN
--Do Something
END
ELSE
BEGIN
--Do Another Thing
END
FOR the best performance, use specific column name instead of * - for example:
SELECT TOP 1 <columnName>
FROM <tableName>
This is optimal because, instead of returning the whole list of columns, it is returning just one. That can save some time.
Also, returning just first row if there are any values, makes it even faster. Actually you got just one value as the result - if there are any rows, or no value if there is no rows.
If you use the table in distributed manner, which is most probably the case, than transporting just one value from the server to the client is much faster.
You also should choose wisely among all the columns to get data from a column which can take as less resource as possible.
Can't you just count the rows using select count(*) from table (or an indexed column instead of * if speed is important)?
If not then maybe this article can point you in the right direction.
Fast:
SELECT TOP (1) CASE
WHEN **NOT_NULL_COLUMN** IS NULL
THEN 'empty table'
ELSE 'not empty table'
END AS info
FROM **TABLE_NAME**