How does 'in' clause works in oracle
Correct (but note that IN
is an operator, not a clause and it works like this in SQL in general, not only for Oracle).
where 1 not in (null,1)
is equivalent to:
where 1 != null and 1 != 1
which should really be written as:
WHERE 1 NOT IN (NULL, 1)
and
WHERE 1 <> NULL AND 1 <> 1
which is the same as:
WHERE (1 <> NULL) AND (1 <> 1)
which evaluates to:
WHERE UNKNOWN AND FALSE
and further as:
WHERE FALSE
So, it correctly returns no rows.
Notice that if you had WHERE 1 NOT IN (NULL, 2)
, it would evaluate to WHERE UNKNOWN
(left as an exercise) and no rows would be returned either.
SQL multiple columns in IN clause
You could do like this:
SELECT city FROM user WHERE (firstName, lastName) IN (('a', 'b'), ('c', 'd'));
The sqlfiddle.
How to put more than 1000 values into an Oracle IN clause
Put the values in a temporary table and then do a select where id in (select id from temptable)
Using LIKE in an Oracle IN clause
What would be useful here would be a LIKE ANY
predicate as is available in PostgreSQL
SELECT *
FROM tbl
WHERE my_col LIKE ANY (ARRAY['%val1%', '%val2%', '%val3%', ...])
Unfortunately, that syntax is not available in Oracle. You can expand the quantified comparison predicate using OR
, however:
SELECT *
FROM tbl
WHERE my_col LIKE '%val1%' OR my_col LIKE '%val2%' OR my_col LIKE '%val3%', ...
Or alternatively, create a semi join using an EXISTS
predicate and an auxiliary array data structure (see this question for details):
SELECT *
FROM tbl t
WHERE EXISTS (
SELECT 1
-- Alternatively, store those values in a temp table:
FROM TABLE (sys.ora_mining_varchar2_nt('%val1%', '%val2%', '%val3%'/*, ...*/))
WHERE t.my_col LIKE column_value
)
For true full-text search, you might want to look at Oracle Text: http://www.oracle.com/technetwork/database/enterprise-edition/index-098492.html
When do we use WITH clause, and what are main benefits of it?
is there any risk of using it?
Yes. Oracle may decide to materialize the subquery, which means writing its result set to disk and then reading it back (except it might not mean that in 12cR2 or later). That unexpected I/O could be a performance hit. Not always, and usually we can trust the optimizer to make the correct choice. However, Oracle has provided us with hints to tell the optimizer how to handle the result set: /*+ materialize */
to um materialize it and /*+ inline */
to keep it in memory.
I start with this potential downside because I think it's important to understand that the WITH clause is not a silver bullet and it won't improve every single query, and may even degrade performance. For instance I share the scepticism of the other commenters that the query you posted is in any way faster because you re-wrote it as a common table expression.
Generally, the use cases for the WITH clause are:
We want to use the result set from the subquery multiple times
with cte as
( select blah from meh )
select *
from t1
join t2 on t1.id = t2.id
where t1.col1 in ( select blah from cte )
and t2.col2 not in ( select blah from cte)We want to be build a cascade of subqueries:
with cte as
( select id, blah from meh )
, cte2 as
( select t2.*, cte.blah
from cte
join t2 on t2.id = cte.id)
, cte3 as
( select t3.*, cte2.*
from cte2
join t3 on t3.col2 = cte2.something )
….
This second approach is beguiling and can be useful for implementing complex business logic in pure SQL. But it can lead to a procedural mindset and lose the power sets and joins. This too is a risk.
We want to use recursive WITH clause. This allows us to replace Oracle's own CONNECT BY syntax with a more standard approach. Find out more
In 12c and later we can write user-defined functions in the WITH clause. This is a powerful feature, especially for users who need to implement some logic in PL/SQL but only have SELECT access to the database. Find out more
For the record I have seen some very successful and highly performative uses of the second type of WITH clause. However I have also seen uses of WITH when it would have been just as easy to write an inline view. For instance, this is just using the WITH clause as syntactic sugar ...
with cte as
( select id, blah from meh )
select t2.*, cte.blah
from t2
join cte on cte.id = t2.id
… and would be clearer as ...
select t2.*, cte.blah
from t2
join ( select id, blah from meh ) cte on cte.id = t2.id
Oracle: What does `(+)` do in a WHERE clause?
Depending on which side of the "=" the "(+) is on, it denotes a LEFT OUTER or a RIGHT OUTER join (in this case, it's a left outer join). It's old Oracle syntax that is sometimes preferred by people who learned it first, since they like that it makes their code shorter.
Best not to use it though, for readability's sake.
Can in line views in oracle sql contain not in clause in the query?
Oracle calls subqueries in the FROM
clause "inline views".
These are generic SELECT
queries. They can contain NOT IN
with subqueries. The problem with your query is a lack of ON
clause and the use of double quotes for a string constant:
select *
from t1 inner join
(select *
from t2
where t2.id not in (select ID from t2 where city = 'Paris')
---------------------------------------------------------^ single quotes
) t2
on t1.? = t2.?
-----^ on clause
Note: I would discourage you from using NOT IN
with subqueries, because they do not work as expected if any returned values are NULL
. (If that is the case, then no rows are returned.)
I advise using NOT EXISTS
instead.
Oracle SQL: How to use more than 1000 items inside an IN clause
Not sure that using so many values in a IN()
is that good, actually -- especially for performances.
When you say "the results are strange", maybe this is because a problem with parenthesis ? What if you try this, instead of what you proposed :
SELECT ...
FROM ...
WHERE ...
AND (
ep_codes IN (...1000 ep_codes...)
OR ep_codes IN (...200 ep_codes...)
)
Does it make the results less strange ?
filters in where statement not working for oracle query
Add ()'s around your OR. assuming all ANDS are meant to be applied to whole set.
WHERE l.ENTITY_GRP NOT LIKE '%Wet%'
AND (l.ENTITY_GRP LIKE 'Implant%' or l.ENTITY_GRP LIKE 'Thermal%')
AND s.DUE_DTTM between sysdate and sysdate +30 ;
What's happening is the OR says bring back any group like thermal regardless if it's not like wet and not within the due_dttm date range.
Related Topics
Calculating SQL Server Row_Number() Over() for a Derived Table
SQL Server Convert Columns to Rows
Phpmyadmin - Total Record Count Varies
SQL Server - Group Records by N Minutes Interval
SQL Server:Return Column Names Based on a Record's Value
Hamming Weight/Population Count in T-Sql
SQL Server: Order by Parameters in In Statement
Pivot Table with Non-Cardinal Values
Problem with MySQL Insert Max()+1
Why Is My Case Expression Non-Deterministic
Why Doesn't Oracle Raise "Ora-00918: Column Ambiguously Defined" for This Query
How to Prevent SQL Injection in Wordpress
How to Ensure Integrity Between Unrelated Tables
How to Return Last Inserted (Auto Incremented) Row Id in Hsql