How to use LIKE in these cases? [duplicate] - postgresql

This question already has answers here:
Regular expression in PostgreSQL LIKE clause
(2 answers)
Closed 10 months ago.
There is a list of countries.
I want to get the list of the countries that:
consist of the letter U and A -or- S
consist of the letter U and any character except S.
These structures are correct for the MS SQL but don't work for Postgres
For MS SQL Server:
SELECT
country
FROM world.country
WHERE country LIKE 'U[AS]%'
SELECT
country
FROM world.country
WHERE country LIKE 'U[S]%'
For Postgres?

You can use SIMILAR TO Documentation
select * from (values ('UAA'),('MUA'),('UUA'),('USA')) as test (country)
where country SIMILAR TO 'U(A|S)%'
returns 'UAA' and 'USA'
You can use also POSIX regular expression with the same result.
select * from (values ('UAA'),('MUA'),('UUA'),('USA')) as test (country)
where country ~ '^U(A|S)'

Related

Subquery not working with NULL data [duplicate]

This question already has answers here:
How does 'in' clause works in oracle
(5 answers)
NOT IN (subquery) producing zero rows
(2 answers)
SQL "select where not in subquery" returns no results
(12 answers)
Why is nothing selected in this select query?
(5 answers)
Correct way to use "NOT IN" Postgres
(4 answers)
Closed 5 years ago.
Today I have seen one weird issue in PostgreSQL query. In which I have 2 tables Products and Parameters.
Purpose:
It's very simple query, I just want to list all products which are not
there in parameter table.
Query:
select
id
from product_proudct
where active=True and
id not in
(
select distinct product_id from parameter_view
)
Issue:
It won't list anything if there is null value in
parameter table in product_id column. I have verified by just removing null record from the parameter table by adding where clause.
select distinct product_id from parameter_view where product_id is not null
And then it's working fine but with null it won't work, it's really
strange for me.
I would like to know the reason why subquery not working well with null ?

Exclude a word in sql query?

I'm trying to write a query in sql to exclude a keyword:
It's a list of cities written out (e.g. AnnArbor-MI). In the list there are duplicates because some have the word 'badsetup' after the city and these need to be discarded. How would I write something to exclude any city with 'badsetup' after it?
Your question title and content appear to be asking for two different things ...
Query cities while excluding the trailing 'badsetup':
SELECT regexp_matches(citycolumn, '(.*)badsetup')
FROM mytable;
Query cities that don't have the trailing 'badsetup':
SELECT citycolumn
FROM mytable
WHERE citycolumn NOT LIKE '%badsetup';
In psql, to select rows excluding those with the word 'badsetup' you can use the following:
SELECT * FROM table_name WHERE column NOT LIKE '%badsetup%';
In this case the '%' indicates that there can be any characters of any length in this space. So this query will find any instance of the phrase 'badsetup' in your column, regardless of the characters before or after it.
You can find more information in section 9.7.1 here: https://www.postgresql.org/docs/8.3/static/functions-matching.html

how to remove my stop words from a string column in postgresql

I have a table with a string column. I want to remove the stop words. I used this query which seems Ok.
SELECT to_tsvector('english',colName)from tblName order by colName asc;
it does not update the column in table
I want to see the stop words of Postgresql and what the query found.Then in case I can replace it with my own file. I also checked this address and could not find the stop words list file. Actually, the address does not exist.
$SHAREDIR/tsearch_data/english.stop
There is no function to do that.
You could use something like this (in this example in German):
SELECT array_to_string(tsvector_to_array(to_tsvector('Hallo, Bill und Susi!')), ' ');
array_to_string
-----------------
bill hallo susi
(1 row)
This removes stop words, but also stems and non-words, and it does not care about word order, so I doubt that the result will make you happy.
If that doesn't fit the bill, you can use regexp_replace like this:
SELECT regexp_replace('Bill and Susi, hand over or die!', '\y(and|or|if)\y', '', 'g');
regexp_replace
-----------------------------
Bill Susi, hand over die!
(1 row)
But that requires that you include your list of stop words in the query string. An improved version would store the stop words in a table.
The chosen answer did not match my requirement, but I found a solution for this:
SELECT regexp_replace('Bill and Susi, hand over or die!', '[^ ]*$','');
regexp_replace
-----------------------------
Bill and Susi, hand over or
(1 row)

Searching individual words in a string

I know about full-text search, but that only matches your query against individual words. I want to select strings that contain a word that starts with words in my query. For example, if I search:
appl
the following should match:
a really nice application
apples are cool
appliances
since all those strings contains words that start with appl. In addition, it would be nice if I could select the number of words that match, and sort based on that.
How can I implement this in PostgreSQL?
Prefix matching with Full Text Search
FTS supports prefix matching. Your query works like this:
SELECT * FROM tbl
WHERE to_tsvector('simple', string) ## to_tsquery('simple', 'appl:*');
Note the appended :* in the tsquery. This can use an index.
See:
Get partial match from GIN indexed TSVECTOR column
Alternative with regular expressions
SELECT * FROM tbl
WHERE string ~ '\mappl';
Quoting the manual here:
\m .. matches only at the beginning of a word
To order by the count of matches, you could use regexp_matches()
SELECT tbl_id, count(*) AS matches
FROM (
SELECT tbl_id, regexp_matches(string, '\mappl', 'g')
FROM tbl
WHERE string ~ '\mappl'
) sub
GROUP BY tbl_id
ORDER BY matches DESC;
Or regexp_split_to_table():
SELECT tbl_id, string, count(*) - 1 AS matches
FROM (
SELECT tbl_id, string, regexp_split_to_table(string, '\mappl')
FROM tbl
WHERE string ~ '\mappl'
) sub
GROUP BY 1, 2
ORDER BY 3 DESC, 2, 1;
db<>fiddle here
Old sqlfiddle
Postgres 9.3 or later has index support for simple regular expressions with a trigram GIN or GiST index. The release notes for Postgres 9.3:
Add support for indexing of regular-expression searches in pg_trgm
(Alexander Korotkov)
See:
PostgreSQL LIKE query performance variations
Depesz wrote a blog about index support for regular expressions.
SELECT * FROM some_table WHERE some_field LIKE 'appl%' OR some_field LIKE '% appl%';
As for counting the number of words that match, I believe that would be too expensive to do dynamically in postgres (though maybe someone else knows better). One way you could do it is by writing a function that counts occurrences in a string, and then add ORDER BY myFunction('appl', some_field). Again though, this method is VERY expensive (i.e. slow) and not recommended.
For things like that, you should probably use a separate/complimentary full-text search engine like Sphinx Search (google it), which is specialized for that sort of thing.
An alternative to that, is to have another table that contains keywords and the number of occurrences of those keywords in each string. This means you need to store each phrase you have (e.g. really really nice application) and also store the keywords in another table (i.e. really, 2, nice, 1, application, 1) and link that keyword table to your full-phrase table. This means that you would have to break up strings into keywords as they are entered into your database and store them in two places. This is a typical space vs speed trade-off.

Update rows from another table [duplicate]

This question already has answers here:
How do I UPDATE from a SELECT in SQL Server?
(38 answers)
Closed 8 years ago.
I have a table with 2 columns, Country and Qty. the field country has distinct acronyms of all the countries. Now my job is to replace those acronyms with the actual country name. Now there is another table with acronyms and corresponding country names. I have to take the values from this second table and update the first one where Acronyms match. Please help..
UPDATE q
SET country = a.country
FROM quantity q
JOIN acronym a
ON a.acronym = q.country