Postgres LIKE with column value as substring - sql

I'm trying to compose a WHERE statement that will match rows where a column value is a substring of another string.
For example, I might have an event record with a name field of Edward Sharpe. I'd like to do something like:
SELECT * FROM events WHERE(name LIKE 'Edward Sharpe and the Magnetic Zeroes');
This doesn't work. I've also various permutations of:
SELECT * FROM events WHERE('%' || name || '%' LIKE 'Edward Sharpe and the Magnetic Zeroes');
Which also doesn't work.

Your second attempt is painfully close to correct. The LIKE keyword takes a string on its left, and a pattern on its right. Both can be expressions, but % only has a special meaning in the pattern to the right.
Try this:
SELECT * FROM events
WHERE name LIKE '%Edward Sharpe and the Magnetic Zeroes%';
Or rather this:
SELECT * FROM events
WHERE 'Edward Sharpe and the Magnetic Zeroes' LIKE '%' || name || '%';
Also note that all string operations in Postgres are case sensitive by default. To match a pattern ignoring case, use ILIKE in place of LIKE.

Related

SQL Using LIKE and ANY at the same time

I have a table with a column feature of type text and a text array (text[]) named args. I need to select from the table those rows in which the feature column contains at least one of the elements of the args array.
I've tried different options, including this:
SELECT * FROM myTable WHERE feature LIKE '%' + ANY (args) + '%';
But that does not work.
The simple solution is to use the regular expression match operator ~ instead, which works with strings in arg as is (without concatenating wildcards):
SELECT *
FROM tbl
WHERE feature ~ ANY(args);
string ~ 'pattern' is mostly equivalent to string LIKE '%pattern%', but not exactly, as LIKE uses different (and fewer) special characters than ~. See:
Escape function for regular expression or LIKE patterns
If that subtle difference is not acceptable, here is an exact implementation of what you are asking for:
SELECT *
FROM tbl t
WHERE t.feature LIKE ANY (SELECT '%' || a || '%' FROM unnest(t.args) a);
Unnest the array, pad each element with wildcards, and use LIKE ANY with the resulting set.
See:
IN vs ANY operator in PostgreSQL

Making a query which selects the news that contain a specific word

CREATE TABLE IF NOT EXISTS news (
title TEXT PRIMARY KEY,
newsletter_description TEXT NOT NULL
);
I need to write a query which selects all the news that contain the word "apple" or "watermelon"(or both) in their title or in their newsletter_description and I am not very sure about how I can do that. (case insensitive, it can also be "AppLe" or "WaterMelon")
SELECT * FROM NEWS
WHERE title LIKE "%apple%" OR
title LIKE "%watermelon%" OR
newsletter_description LIKE "%apple%" OR
newsletter_description LIKE "%watermelon%
SQlite implemented LIKE operator case insensitive for ASCII characters by default. Unless you use unicode characters in your text you can use above query.
However if you use unicode chars, using lower or upper functions doesn't work either. So there is no point in using lower or upper functions at all.
https://www.sqlite.org/c3ref/strlike.html
You can use « lower(title) like '%apple%' »
In fact the lower put all the field in minuscule, that help you to find the word needed without knowing how he is written
You can use like operator and to have case insensitive search you can either use lower or upper on the actual column and also have to convert the input to lower/upper before passing to the query accordingly,
select *
from news
where lower(newsletter_description) like '%watermelon%'
or lower(newsletter_description) like '%apple%'
or lower(title) like '%watermelon%'
or lower(title) like '%apple%';
Use a CTE that returns all the words that you search for and join it to the table:
with cte(word) as (values ('apple'), ('watermelon'))
select n.*
from news n inner join (select '%' || word || '%' word from cte) c
on n.title like c.word or n.newsletter_description like c.word
Naive way will be select * from new where lower(title) like ‘%apple%’ or lower(title) like ‘%watermelon%’ or lower(newsletter_description) like ‘%apple%’ or lower(newsletter_description) like ‘%watermelon%’;

using wildcard and 'like' to compare contents of two columns in pgSQL

i have columns in two separate tables that i'm using in a join and subsequent update. i want to be able to see if one column has all of its content captured in a second column.
for instance, here is a sample of contents from each column:
city_table1 | city_table2
Portsmouth Portsmouth, New Hampshire, USA
i want to be able to have a where clause in a select statement that will match the two columns based on the contents in city_table1 (but i can't just do a left or right trim based on content variance), so i'm envisioning something like
where city_table1 like ('%' + city_table2 '%')
is my logic off here? should i referse the two fields in this where clause? i've tried this in postgres and got no results when i know it should work if i have the syntax right.
thank you!
Postgres uses || to concatenate strings. So:
where city_table2 like ('%' || city_table1 || '%')
Also, you have the comparison backwards. The shorter string is surrounded by the '%'.
And, this would be simpler with regular expressions:
where city_table2 ~ city_table1

Full Text Search Using Multiple Partial Words

I have a sql server database that has medical descriptions in it. I've created a full text index on it, but I'm still figuring out how this works.
The easiest example to give is if there is a description of Hypertensive heart disease
Now they would like to be able to type hyp hea as a search term and have it return that.
So from what I've read it seems like my query needs to be something like
DECLARE #Term VARCHAR(100)
SET #Term = 'NEAR(''Hyper*'',''hea*'')'
SELECT * FROM Icd10Codes WHERE CONTAINS(Description, #Term)
If I take the wild card out for Hypertensive and heart, and type out the full words it works, but adding the wild card in returns nothing.
If it makes any difference I'm using Sql Server 2017
So it was a weird syntax issue that didn't cause an error, but stopped the search from working.
I changed it to
SELECT * FROM Icd10Codes where CONTAINS(description, '"hyper*" NEAR "hea*"')
The key here being I needed double quotes " and not to single quotes. I assumed it was two single quotes, the first to escape the second, but it was actually double quotes. The above query returns the results exactly as expected.
this will work:
SELECT * FROM Icd10Codes where SOUNDEX(description)=soundex('Hyp');
SELECT * FROM Icd10Codes where DIFFERENCE(description,'hyp hea')>=2;
You could try a like statement. You can find a thorough explanation here.
Like so:
SELECT * FROM Icd10Codes WHERE Icd10Codes LIKE '%hyp hea%';
And then instead of putting the String in there just use a variable.
If you need to search for separated partial words, as in an array of search terms, it gets a bit tricky, since you need to dynamically build the SQL statement.
MSSQL provides a few features for full text search. You can find those here. One of them is the CONTAINS keyword:
SELECT column FROM table WHERE CONTAINS (column , 'string1 string2 string3');
For me - this had more mileage.
create a calculated row with fields as full text search.
fullname / company / lastname all searchable.
ALTER TABLE profiles ADD COLUMN fts tsvector generated always as (to_tsvector('english', coalesce(profiles.company, '') || ' ' || coalesce(profiles.broker, '') || ' ' || coalesce(profiles.firstname, '') || ' ' || coalesce(profiles.lastname, '') || ' ' )) stored;
let { data, error } = await supabase.from('profiles')
.select()
.textSearch('fts',str)

SQL: cut a field, then search

I would like to perform a "on the fly" modification of a field of a sqlite database, before doing a SELECT statement.
The field is called 'topic_simple', and it contains some text. Somewhere in the text, there is a kind of separator I included: 4 spaces: " ".
Here is one of my typical SELECT statement:
SELECT * FROM papers WHERE (topic_simple LIKE '% 3D print%')
I would like something like that:
SELECT * FROM papers WHERE ((topic_simple_before_4_spaces) LIKE '% 3D print%')
I DO NOT WANT to modify topic_simple in the database, I just want to make a select statement on a substring of this field.
How can I do that ?
LIKE is quite powerful. Why don't you just add the four spaces to your LIKE expression:
SELECT *
FROM papers
WHERE topic_simple LIKE '% 3D print% %';
Be aware that the text after your delimiter shouldn't contain the delimiter because then you'd possibly get unwanted lines. If your SQLite supports it, you can also use a regular expression.
In MYSQL you can directly "select" (or "extract") the text before your four spaces in the WHERE clause:
SELECT *
FROM papers
WHERE SUBSTRING(topic_simple, 1, LOCATE(' ', topic_simple) - 1) ...;