SQL IN Statement using like syntax? [duplicate] - sql

This question already has answers here:
Is there a combination of "LIKE" and "IN" in SQL?
(28 answers)
Closed 9 years ago.
I would like to do something like this i.e., use wild card characters in the in clause:
SELECT * FROM mytable WHERE keywords IN ('%test%', '%testing%')
This is not supported in SQL Server.... Is there some other way to achieve it...
Looking for something other than:
SELECT * FROM mytable WHERE keywords like '%test%' or keywords like '%testing%' or.....

Nope, only other way I can think of is joining in to a temp table but then you have to eliminate duplicate rows.
This query of yours is horribly inefficient as it will unconditionally table scan. Perhaps you should look at separating the keywords or introducing a full text index.
If you would like to look into doing full text searches, then I would recommend looking into some of the heavy weights out there like sphinx or lucene when you evaluate the Sql Server full-text solution.

SELECT DISTINCT *
FROM
mytable M
JOIN
(
SELECT '%test%' AS pattern
UNION ALL SELECT '%testing%'
...
) foo ON M.keywords LIKE foo.Pattern
Could be a CTE or temp table too

This is not supported in MS SQL.... Is
there some other way to achieve it?
Yes, Full Text Search. At least for prefix wildcards.

You can use Regular Expression to do this.
In one Regular Expression you can define as many pattern as you want in one expression.
There are lot's of article about Regular Expression Matching in MS SQL SERVER.
I used RLIKE in MySQL to do Regular Expression Matching.
I also attached link1 & link2 for MS SQL SERVER Regular Expression Matching.

Related

Compare String with "like" against a list

is it possible to compare a string against a list using "like" and wildcards, so sth like
select column
from table
where column like('%foo%', '%bar%')
The example does not work in any database format I know. How can I do this without using a verbose solution like
select column
from table
where column like'%foo%' or column like '%bar%'
I am interested in a platform-independent solution but mainly Sybase ASE.
Thanks very much!
If you are using MySQL/PostgreSQL you could use regexp, that is one way.
SELECT column FROM table WHERE (column REGEXP '^ALA[0-9]')
http://dev.mysql.com/doc/refman/5.0/en/regexp.html#operator_regexp
http://www.oreillynet.com/pub/a/databases/2006/02/02/postgresq_regexes.html
Second solution would be, mentioned by you creating many likes, joined by or.

Replacement for 'OR' in SphinxQL

I'm currently trying to integrate Sphinx search engine into Python application. The problem is that SphinxQL doesn't support OR clause as common SQL does. There are some hacks to use, like writing expressions in SELECT like this:
SELECT id,(field1 = val1 OR field2 = val2) as expr FROM foo_bar WHERE expr = 1;
However, it doesn't work with strings, because they should be handled using MATCH function. So I decided to divide query into separate subqueries and combine results obtained. Yet there's still a problem of getting a proper META information, especially the total_found field. Sphinx counts it for separate queries, but rows obtained from these queries may intersect and I have no ability to check it (database is large).
I believe there must be a solution. I'm using Sphinxit (SphinxAlchemy has a version conflict with SQLAlchemy I'm using).
Repost from SphinxSearch forum:
I have a table I need to search in with text and numerical columns as well. I need to
write a query with OR condition; found out that there's a way to do it using SELECT
expressions like:
SELECT *, quantity>=50 OR quantity=0 AS mycond FROM table1 WHERE mycond = 1;
Hopelessly it doesn't work with string attributes. This query isn't parsed:
SELECT *, category='foo' OR category='bar' AS mycond FROM table1 WHERE mycond = 1;
Yet this is working in Beta 2.2.3:
SELECT * FROM table1 WHERE category='foo';
What should I do to find count of rows that fit one of conditions, not every one of them?
I can make a few queries and merge obtained items into one list, but I need to now how
much of these rows are in the database now.
For attribute / facet OR'ing, I think you're correct that the only way is to put an expression in the SELECT clause.
For strings, though, check out the documentation on the fulltext query syntax. You can't exactly use the OR keyword, but something like this should work:
SELECT id, name
FROM recipes
WHERE MATCH('(#ingredients chocolate) | (#name cake)')
LIMIT 10;

how to use many LIKE conditions in SQL easily? [duplicate]

This question already has answers here:
Combining "LIKE" and "IN" for SQL Server [duplicate]
(5 answers)
Closed 9 years ago.
I want to use many LIKE conditions in my query. I couldn't find a practical solution. I tried CONTAINS but it doesn't work.
Instead of using this
where EIO.DigiAddress like '%abc#abc.com%'
or EIO.DigiAddress like '%def#def.com%'
or EIO.DigiAddress like '%ghi#ghi.com%'
I want to use something like this:
CONTAINS(EIO.DigiAddress,'%abc#abc.com%', '%def#def.com%', '%ghi#ghi.com%')
OR
EIO.DigiAddress IN ('%abc#abc.com%', '%def#def.com%', '%ghi#ghi.com%')
Try this:
Create a temp table:
CREATE TEMPORARY TABLE temp (
alternate VARCHAR(20)
);
then:
INSERT INTO temp
VALUES ('%abc#abc.com%'), ('%def#def.com%'), ('%ghi#ghi.com%');
Select:
SELECT t.*
FROM tbl t JOIN temp p ON (t.col LIKE p.alternate);
I don't see anything wrong in using LIKE. But if you don't like LIKE then use this (for MS SQLSERVER)
where PATINDEX('%abc#abc.com%', EIO.DigiAddress) >0 OR
PATINDEX('%def#def.com%', EIO.DigiAddress) >0 OR
PATINDEX('%ghi#ghi.com%', EIO.DigiAddress) >0
Note: You have to use relevant string function for PATINDEX depending on the database you use.
You can do this with regular expressions:
where EIO.DigiAddress regexp '[a-c|e-g|g-i]{3}#{1}[a-c|e-g|g-i]{3}.com'

How does phpmyadmin implement "search" feature?

In phpMyAdmin, there is a search in database feature by which I can input a word and find it in any table(s).
How to implement it by SQL statement? I know the LIKE operation, but it's syntax is:
WHERE column_name LIKE pattern
How to search in all columns? Any how to specify it's a exact keyword or regular express?
SELECT * FROM your_table_name WHERE your_column_name LIKE 'search_box_text';
Where search_box_text is what you enter in the search. It will also say in the result page what kind of query it made. The same query with regular expressions is:
SELECT * FROM your_table_name WHERE your_column_name REGEXP 'search_box_text';
Remember that the wildcard in mysql is %. Eg. "LIKE '%partial_search_text%'
If you want to search in multiple columns, you can check which columns are in table with:
DESCRIBE TABLE your_table_name;
Or if you already know your columns:
SELECT * FROM your_table_name
WHERE your_column_1 LIKE '%search%'
AND your_column_2 LIKE '%search%'
AND your_column_3 LIKE '%search%';

Make an SQL request more efficient and tidy?

I have the following SQL query:
SELECT Phrases.*
FROM Phrases
WHERE (((Phrases.phrase) Like "*ing aids*")
AND ((Phrases.phrase) Not Like "*getting*")
AND ((Phrases.phrase) Not Like "*contracting*"))
AND ((Phrases.phrase) Not Like "*preventing*"); //(etc.)
Now, if I were using RegEx, I might bunch all the Nots into one big (getting|contracting|preventing), but I'm not sure how to do this in SQL.
Is there a way to render this query more legibly/elegantly?
Just by removing redundant stuff and using a consistent naming convention your SQL looks way cooler:
SELECT *
FROM phrases
WHERE phrase LIKE '%ing aids%'
AND phrase NOT LIKE '%getting%'
AND phrase NOT LIKE '%contracting%'
AND phrase NOT LIKE '%preventing%'
You talk about regular expressions. Some DBMS do have it: MySQL, Oracle... However, the choice of either syntax should take into account the execution plan of the query: "how quick it is" rather than "how nice it looks".
With MySQL, you're able to use regular expression where-clause parameters:
SELECT something FROM table WHERE column REGEXP 'regexp'
So if that's what you're using, you could write a regular expression string that is possibly a bit more compact that your 4 like criteria. It may not be as easy to see what the query is doing for other people, however.
It looks like SQL Server offers a similar feature.
Sinec it sounds like you're building this as you go to mine your data, here's something that you could consider:
CREATE TABLE Includes (phrase VARCHAR(50) NOT NULL)
CREATE TABLE Excludes (phrase VARCHAR(50) NOT NULL)
INSERT INTO Includes VALUES ('%ing aids%')
INSERT INTO Excludes VALUES ('%getting%')
INSERT INTO Excludes VALUES ('%contracting%')
INSERT INTO Excludes VALUES ('%preventing%')
SELECT
*
FROM
Phrases P
WHERE
EXISTS (SELECT * FROM Includes I WHERE P.phrase LIKE I.phrase) AND
NOT EXISTS (SELECT * FROM Excludes E WHERE P.phrase LIKE E.phrase)
You are then always just running the same query and you can simply change what's in the Includes and Excludes tables to refine your searches.
Depending on what SQL server you are using, it may support REGEX itself. For example, google searches show that SQL Server, Oracle, and mysql all support regex.
You could push all your negative criteria into a short circuiting CASE expression (works Sql Server, not sure about MSAccess).
SELECT *
FROM phrases
WHERE phrase LIKE '%ing aids%'
AND CASE
WHEN phrase LIKE '%getting%' THEN 2
WHEN phrase LIKE '%contracting%' THEN 2
WHEN phrase LIKE '%preventing%' THEN 2
ELSE 1
END = 1
On the "more efficient" side, you need to find some criteria that allows you to avoid reading the entire Phrases column. Double sided wildcard criteria is bad. Right sided wildcard criteria is good.