SQL query combination of like and in? [duplicate] - sql

This question already has answers here:
Is there a combination of "LIKE" and "IN" in SQL?
(28 answers)
Closed 7 years ago.
a. Select * from tableA where columnA like '%complete%';
b. Select * from tableA where columnA in ('complete','request');
The possible value for columnA is complete, completed, request, requested..............
My objective is to query those with value complete, completed, request, requested
Normally we will write query where columnA in ('complete','completed','request','requested');
Is there a way to write a much shorter query like Select * from tableA where columnA in like (%complete%, %request%) ?

You need to use multiple OR:
select *
from tableA
where columnA like '%complete%'
or columnA like '%requested%'
or ...
Use Join:
SELECT *
FROM tableA t
JOIN VALUES (('%complete%'), ('%requested%'), ...) v(c)
ON t.columnA LIKE v.c
Be aware that search pattern %phrase% is not SARG-able and query optimizer won't use index on that column, if exists any.
You should consider usage of Full-Text Search

You can try using CONTAINS like this:
select * from tableA
WHERE CONTAINS(columnA, '"complete*" OR "requested*" OR ...')

Related

Compare varchar values postgresql

I'm new in the db world and I'm trying to do my first queries.
I have two tables and I need compare the value of the columnA, in the first table, with the value of the columnB in the second table.
I would like to know what values in the columnA are in the columnB. Both columns are varchar type.
I've tried this two queries:
select *
from tableA
join tableB
on (tableA.columnA = tableB.columnB);
select *
from tableA
where columnA in (select columnB
from tableB);
But both get me back empty table.
I checked the values manually, and there are many equal values.
Maybe the = isn't the right operator with the string values?
This is a simple example of what I would do, with the expected result at the end.
TableA
columnA descriptionA
EF8236PA xyx
EF7843DV dgfd
EF6535MD dshr
EF3274LK hghg
EF6940BN fdtsg
EF3405TJ dsbfbs
TableB
columnB
EF3405TJ
EF6940BN
EF6535MD
Result:
EF3405TJ
EF6940BN
EF6535MD
Both of your queries are looking fine. you can add few more conditions in the where clause that will make it work.
Example:
select *
from tableA
join tableB
on (upper(trim(tableA.columnA)) = upper(trim(tableB.columnB)));
Trim will cut down extra spaces and upper will make the search case insensitive.
Hope this will help.
I would like to know what values in the columnA are in the columnB.
Strictly speaking, this query is a correct (and fast) query to implement what you ask:
SELECT DISTINCT columnA
FROM tableA a
WHERE EXISTS (SELECT 1 FROM tableB WHERE columnB = a.columnA);
The manual about EXISTS.
But neither of your queries should return empty sets. There may be whitespace or other invisible characters fooling you. Test with:
SELECT * FROM tableA WHERE columnA = 'EF6940BN';
SELECT * FROM tableB WHERE columnB = 'EF6940BN';
I tried all your suggestions, but no one works.
So I tried run the code on another postgre and the same code that I wrote above works.
I don't understand why, the postgre's versions are the same

Oracle: Mixing IN and LIKE, is it possible? [duplicate]

This question already has answers here:
How can I introduce multiple conditions in LIKE operator?
(10 answers)
Closed 8 years ago.
Is it possible to do someting like this?
Ie.
IN ('%1', '%2')
The values are not few
How would you solve this task?
You could also use REGEXP_LIKE instead of LIKE. It can be more flexible in this type of situation.
To get everything that ends with '1' or '2' just use:
SELECT * FROM table_name WHERE REGEXP_LIKE(col_name, '[12]$')
The [12] means match 1 or 2. The $ means match the end of the string.
If you need something such as this:
LIKE '%1' OR LIKE '%2' or LIKE '%A' or LIKE '%W'
... you just have to add the other characters within the square brackets:
SELECT * FROM table_name WHERE REGEXP_LIKE(col_name, '[12AW]$')
Or, if you wanted anything that ends with a digit you could use this:
SELECT * FROM table_name WHERE REGEXP_LIKE(col_name, '[[:digit:]]$'
If you have only a few, just combine them with or:
column like '%1' or column like '%2' or...
If you have a lot, you can create a table with the patterns and join to it.
create table matches (
match char(10)
);
insert into matches values
('%1'),('%2'),...;
select * from table
inner join matches on table.column like matches.match;
That has some issues with duplicate rows if a single row matches more than one pattern, but you can modify it depending on what kind of final output you want.
As a third option, you could use substr() rather than like if they are all the same length:
select * from table where substr(column,-1,1) in ('1','2',...)
This checks if the last character is in the set of values.
How about using like itself?
Column LIKE '%1' OR Column LIKE '%2'
Basically same as examples of others but closest to your example:
SELECT deptno, empno, ename FROM scott.emp
WHERE job IN
(SELECT job FROM scott.emp WHERE job Like ('SALE%') OR job Like ('MANAG%'))
/

Using LIKE in an Oracle IN clause

I know I can write a query that will return all rows that contain any number of values in a given column, like so:
Select * from tbl where my_col in (val1, val2, val3,... valn)
but if val1, for example, can appear anywhere in my_col, which has datatype varchar(300), I might instead write:
select * from tbl where my_col LIKE '%val1%'
Is there a way of combing these two techniques. I need to search for some 30 possible values that may appear anywhere in the free-form text of the column.
Combining these two statements in the following ways does not seem to work:
select * from tbl where my_col LIKE ('%val1%', '%val2%', 'val3%',....)
select * from tbl where my_col in ('%val1%', '%val2%', 'val3%',....)
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
A REGEXP_LIKE will do a case-insensitive regexp search.
select * from Users where Regexp_Like (User_Name, 'karl|anders|leif','i')
This will be executed as a full table scan - just as the LIKE or solution, so the performance will be really bad if the table is not small. If it's not used often at all, it might be ok.
If you need some kind of performance, you will need Oracle Text (or some external indexer).
To get substring indexing with Oracle Text you will need a CONTEXT index. It's a bit involved as it's made for indexing large documents and text using a lot of smarts. If you have particular needs, such as substring searches in numbers and all words (including "the" "an" "a", spaces, etc) , you need to create custom lexers to remove some of the smart stuff...
If you insert a lot of data, Oracle Text will not make things faster, especially if you need the index to be updated within the transactions and not periodically.
No, you cannot do this. The values in the IN clause must be exact matches. You could modify the select thusly:
SELECT *
FROM tbl
WHERE my_col LIKE %val1%
OR my_col LIKE %val2%
OR my_col LIKE %val3%
...
If the val1, val2, val3... are similar enough, you might be able to use regular expressions in the REGEXP_LIKE operator.
Yes, you can use this query (Instead of 'Specialist' and 'Developer', type any strings you want separated by comma and change employees table with your table)
SELECT * FROM employees em
WHERE EXISTS (select 1 from table(sys.dbms_debug_vc2coll('Specialist', 'Developer')) mt
where em.job like ('%' || mt.column_value || '%'));
Why my query is better than the accepted answer: You don't need a CREATE TABLE permission to run it. This can be executed with just SELECT permissions.
In Oracle you can use regexp_like as follows:
select *
from table_name
where regexp_like (name, '^(value-1|value-2|value-3....)');
The caret (^) operator to indicate a beginning-of-line character &
The pipe (|) operator to indicate OR operation.
This one is pretty fast :
select * from listofvalue l
inner join tbl on tbl.mycol like '%' || l.value || '%'
Just to add on #Lukas Eder answer.
An improvement to avoid creating tables and inserting values
(we could use select from dual and unpivot to achieve the same result "on the fly"):
with all_likes as
(select * from
(select '%val1%' like_1, '%val2%' like_2, '%val3%' like_3, '%val4%' as like_4, '%val5%' as like_5 from dual)
unpivot (
united_columns for subquery_column in ("LIKE_1", "LIKE_2", "LIKE_3", "LIKE_4", "LIKE_5"))
)
select * from tbl
where exists (select 1 from all_likes where tbl.my_col like all_likes.united_columns)
I prefer this
WHERE CASE WHEN my_col LIKE '%val1%' THEN 1
WHEN my_col LIKE '%val2%' THEN 1
WHEN my_col LIKE '%val3%' THEN 1
ELSE 0
END = 1
I'm not saying it's optimal but it works and it's easily understood. Most of my queries are adhoc used once so performance is generally not an issue for me.
select * from tbl
where exists (select 1 from all_likes where all_likes.value = substr(tbl.my_col,0, length(tbl.my_col)))
You can put your values in ODCIVARCHAR2LIST and then join it as a regular table.
select tabl1.* FROM tabl1 LEFT JOIN
(select column_value txt from table(sys.ODCIVARCHAR2LIST
('%val1%','%val2%','%val3%')
)) Vals ON tabl1.column LIKE Vals.txt WHERE Vals.txt IS NOT NULL
You don't need a collection type as mentioned in https://stackoverflow.com/a/6074261/802058. Just use an subquery:
SELECT *
FROM tbl t
WHERE EXISTS (
SELECT 1
FROM (
SELECT 'val1%' AS val FROM dual
UNION ALL
SELECT 'val2%' AS val FROM dual
-- ...
-- or simply use an subquery here
)
WHERE t.my_col LIKE val
)

Combining "LIKE" and "IN" for SQL Server [duplicate]

This question already has answers here:
Is there a combination of "LIKE" and "IN" in SQL?
(28 answers)
Closed 9 years ago.
Is it possible to combine LIKE and IN in a SQL Server-Query?
So, that this query
SELECT * FROM table WHERE column LIKE IN ('Text%', 'Link%', 'Hello%', '%World%')
Finds any of these possible matches:
Text, Textasd, Text hello, Link2, Linkomg, HelloWorld, ThatWorldBusiness
etc...
Effectively, the IN statement creates a series of OR statements... so
SELECT * FROM table WHERE column IN (1, 2, 3)
Is effectively
SELECT * FROM table WHERE column = 1 OR column = 2 OR column = 3
And sadly, that is the route you'll have to take with your LIKE statements
SELECT * FROM table
WHERE column LIKE 'Text%' OR column LIKE 'Hello%' OR column LIKE 'That%'
I know this is old but I got a kind of working solution
SELECT Tbla.* FROM Tbla
INNER JOIN Tblb ON
Tblb.col1 Like '%'+Tbla.Col2+'%'
You can expand it further with your where clause etc.
I only answered this because this is what I was looking for and I had to figure out a way of doing it.
One other option would be to use something like this
SELECT *
FROM table t INNER JOIN
(
SELECT 'Text%' Col
UNION SELECT 'Link%'
UNION SELECT 'Hello%'
UNION SELECT '%World%'
) List ON t.COLUMN LIKE List.Col
No, you will have to use OR to combine your LIKE statements:
SELECT
*
FROM
table
WHERE
column LIKE 'Text%' OR
column LIKE 'Link%' OR
column LIKE 'Hello%' OR
column LIKE '%World%'
Have you looked at Full-Text Search?
No, MSSQL doesn't allow such queries. You should use col LIKE '...' OR col LIKE '...' etc.

Is there any way to combine IN with LIKE in an SQL statement?

I am trying to find a way, if possible, to use IN and LIKE together. What I want to accomplish is putting a subquery that pulls up a list of data into an IN statement. The problem is the list of data contains wildcards. Is there any way to do this?
Just something I was curious on.
Example of data in the 2 tables
Parent table
ID Office_Code Employee_Name
1 GG234 Tom
2 GG654 Bill
3 PQ123 Chris
Second table
ID Code_Wildcard
1 GG%
2 PQ%
Clarifying note (via third-party)
Since I'm seeing several responses which don't seems to address what Ziltoid asks, I thought I try clarifying what I think he means.
In SQL, "WHERE col IN (1,2,3)" is roughly the equivalent of "WHERE col = 1 OR col = 2 OR col = 3".
He's looking for something which I'll pseudo-code as
WHERE col IN_LIKE ('A%', 'TH%E', '%C')
which would be roughly the equivalent of
WHERE col LIKE 'A%' OR col LIKE 'TH%E' OR col LIKE '%C'
The Regex answers seem to come closest; the rest seem way off the mark.
I'm not sure which database you're using, but with Oracle you could accomplish something equivalent by aliasing your subquery in the FROM clause rather than using it in an IN clause. Using your example:
select p.*
from
(select code_wildcard
from second
where id = 1) s
join parent p
on p.office_code like s.code_wildcard
In MySQL, use REGEXP:
WHERE field1 REGEXP('(value1)|(value2)|(value3)')
Same in Oracle:
WHERE REGEXP_LIKE(field1, '(value1)|(value2)|(value3)')
Do you mean somethign like:
select * FROM table where column IN (
SELECT column from table where column like '%%'
)
Really this should be written like:
SELECT * FROM table where column like '%%'
Using a sub select query is really beneficial when you have to pull records based on a set of logic that you won't want in the main query.
something like:
SELECT * FROM TableA WHERE TableA_IdColumn IN
(
SELECT TableA_IdColumn FROM TableB WHERE TableA_IDColumn like '%%'
)
update to question:
You can't combine an IN statement with a like statement:
You'll have to do three different like statements to search on the various wildcards.
You could use a LIKE statement to obtain a list of IDs and then use that in the IN statement.
But you can't directly combine IN and LIKE.
Perhaps something like this?
SELECT DISTINCT
my_column
FROM
My_Table T
INNER JOIN My_List_Of_Value V ON
T.my_column LIKE '%' + V.search_value + '%'
In this example I've used a table with the values for simplicity, but you could easily change that to a subquery. If you have a large list (like tens of thousands) then performance might be rough.
select *
from parent
where exists( select *
from second
where office_code like trim( code_wildcard ) );
Trim code_wildcard just in case it has trailing blanks.
You could do the Like part in a subquery perhaps?
Select * From TableA Where X in (Select A from TableB where B Like '%123%')
tsql has the contains statement for a full-text-search enabled table.
CONTAINS(Description, '"sea*" OR "bread*"')
If I'm reading the question correctly, we want all Parent rows that have an Office_code that matches any Code_Wildcard in the "Second" table.
In Oracle, at least, this query achieves that:
SELECT *
FROM parent, second
WHERE office_code LIKE code_wildcard;
Am I missing something?