PLSQL search string using LIKE backwards - sql

I have a view which has VARCHAR2 column. The column contains a string
which is concatenation of 2 columns from a different table.
For example I search "James Smith".
I search the column using LIKE:
LOWER(USER_LIST.SEARCH_STRING) LIKE LOWER 'James Smith'
I get the results just fine.
I would like to know if there's an option to perform a reverse search (still using LIKE) and getting the same results, like so:
LOWER(USER_LIST.SEARCH_STRING) LIKE LOWER 'Smith James'
Please note that I'm aware that using regex or adding an additional column to the view can resolve this, but I wish to make as minimal changes as possible.
Thanks in advance.

I hope the below answer illustrates your requirement.
SELECT A.NM
FROM
(SELECT 'Avrajit Roy' nm FROM dual
)A
WHERE lower(A.NM) LIKE lower('avrajit roy')
OR TRIM(lower(SUBSTR(a.nm,instr(a.nm,' ',1)+1,LENGTH(a.nm))
||' '
||SUBSTR(a.nm,1,instr(a.nm,' ',1)))) LIKE lower('roy avrajit');

Related

Regex to capture pattern with sql

Given the cell data shown below is of column 'Feed'
hdfs//sddad/aa/vv/cc/SR_DC_EF_GF_20181130_20156478907000_484658274168_CO.dat
i am trying to use a regex method to only display this value 'SR_DC_EF_GF'. Currently i am manually doing a regex method by date which i dont feel its dynamic enough. e,g
select `regexp_replace([Feed], '_2018.*', '')` from tablename.
this will only display and does regex on table that is _20181130. but if i were to have _2019 and _2020, it wont capture and display the whole value. how we can make this regex method dynamic where it can capture other dates?
You could look for four digits:
select regexp_replace([Feed], '_[0-9]{4}.*', '')
from tablename;
However, you are only getting rid of the suffix. I think you want something like this to extract the piece you are looking for:
select regexp_replace([Feed], '^.*([^/0-9]+)_[0-9]{4}.*$', '\1')
from tablename;

Similar to with regex in Postgresql

In Postgresql database I have a column called names where I have some names which need to be parsed using regex to clean up punctuation parts. I am able to get a clean name using regexp_replace as follows:
select regexp_replace(name,'\.COM|''[A-Z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)','','g')
from tableA
However, I would like to compare with some strings that are also cleaned of punctuation. How can I use similar to with the formed regular expression?
select name
from tableA
where (lower(name) ~ '\.COM|''[A-Za-z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)') as nameParsed similar to '(fg )%' and
(lower(name) ~ '\.COM|''[A-Za-z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)') as nameParsed similar to '%( cargo| carrier| cartage )%'
With the previous query I am getting this error:
LINE 3: ...-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)') as namePar...
I have tried in where clause like this and it seems to be working:
select name
from tableA
where (select lower(regexp_replace(name,'\.COM|''[A-Z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)','','g'))) similar to '(fg )%'
Is this the best approach? The execution time went to 46 seconds :(
Thanks in advance
You're trying to get a column name in a WHERE clause (is a comparison, not a column). So, you can use as follows:
SELECT name
FROM "tableA"
WHERE (regexp_replace(name,'\.COM|''[A-Z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)','','g') similar to '(fg )%'
OR regexp_replace(name,'\.COM|''[A-Z]|[^a-zA-Z0-9 -]+|\s(?=&)|(?<!\w\w)(?:\s+|-)(?!\w\w)','','g') similar to '%( cargo| carrier| cartage )%');
Alternatively, you can use ilike instead of similar to if you want to find a specific word.

how to query some characters in one field?

My database is Oracle 11g.
I want to do a in query in sql. The query criteria is to matched some of the characters of a field:
description
CWLV321900017391;EFHU3832239
CWLV321900017491;ERHU3832239
CWLV321900017591;ERHU3832239
CWLV321900017691;ERHU3832239
My query is like this:
select * from product where description in ('CWLV321900017391', 'CWLV321900017491');
It returns no records in result.
I expect the result like below:
description
CWLV321900017391;EFHU3832239
CWLV321900017491;ERHU3832239
How to get it by SQL?
thanks.
You are using IN to search for a partial string match in the description table. This is not going to return the results, as IN will only match exact values.
Instead, one way to achieve this is to use a LIKE operator with %:
select *
from product
where (description LIKE 'CWLV321900017391%' OR
description LIKE 'CWLV321900017491%');
The % at the end indicates that anything can follow after the specified text.
This will return any description that starts with CWLV321900017391 or CWLV321900017491.
Incidentally, if your search term occurs anywhere in the description field, you will need to use a % at each end of the search term:
description LIKE '%CWLV321900017391%' OR description LIKE '%CWLV321900017491%'
There are various ways to solve it. Here is one:
select * from product
where instr (description, 'CWLV321900017391') > 0
or instr (description, 'CWLV321900017491') > 0;
If you know you're always searching for the start of the description you can use:
select * from product
where substr (description, 1, 16) in ('CWLV321900017391','CWLV321900017491')
Also, there's LIKE or REGEX_LIKE solution. It depends really on what strings you're searching for.
Of course none of these solutions is truly satisfactory, and for large volumes of data may exhibit suck-y performance. The problem is the starting data model violates First Normal Form by storing non-atomic values. Poor data models engender clunky SQL.
You can try below way -
select * from product
where substr(description,1,instr(description,';',1,1)-1) in ('CWLV321900017391', 'CWLV321900017491')
I am opposed to storing multiple values in a delimited string format. There are many better alternatives, but let me assume that you don't have a choice on the data model.
If you are stuck with strings in this format, you should take the delimiters into account. You can do this using like:
where ';' || description || ';' like '%;CWLV321900017391;%'
You can also do something similar with regexp_like() if you want to look for one of several values:
where regexp_like(';' || description || ';',
'(;CWLV321900017391;)|(;CWLV321900017391;)'
)

SELECT middle part of a String if it exists. Postgresql

i've got a problem with transferring "real-World" data into my schema.
It's actually a "project" for my Database course and they gave us ab table with dog race results. This Table has a column which contains the name of the Dog (which itself consists of the actuall name and the name of the breeder) and informations about the Birthcountry, actual living Country and the birth year.
Example filed are "Lillycette [AU 2012]" or "Black Bear Lee [AU/AU 2013]" or "Lemon Ralph [IE/UK 1998]".
I've managed it to get out the first word and save it in the right column with split_part like this:
INSERT INTO tblHund (rufname)
SELECT
split_part(name, ' ', 1) AS rufname,
FROM tblimport;
tblimport is a table where I dumped the data from the csv file.
That works just as it should.
Accessing the second part of the Name with this fails because sometimes there isn't a second part and sometimes times there second part consists of two words.
And this is the where iam stuck right now.
I tried it with substring and regular expressions:
INSERT INTO tblZwinger (Name)
SELECT
substring(vatertier from E'[^ ]*\\ ( +)$')AS Name
FROM tblimport
WHERE substring(vatertier from E'[^ ]*\\ ( +)$') != '';
The above code is executed without errors but actually does nothing because the SELECT statement just give empty strings back.
It took me more then 3h to understand a bit of this regular Expressions but I still feel pretty stupid when I look at them.
Is there any other way of doing this. If so just give me a hint.
If not what is wrong with my expression above?
Thanks for your help.
You need to use atom ., which matches any single character inside capturing group:
E'[^ ]*\\ (.+)$'
SELECT
tblimport.*,
ti.parts[1] as f1,
ti.parts[2] as f2, -- It should be the "middle part"
ti.parts[3] as f3
FROM
tblimport,
regexp_matches(tblimport.vatertier, '([^\s]+)\s*(.*)\s+\[(.*)\]') as ti(parts)
WHERE
nullif(ti.parts[2], '') is not null
Something like above.

SQL fetch results by concatenating words in column

I have column store_name (varchar). In that column I have entries like prime sport, best buy... with a space. But when user typed concatenated string like primesport without space I need to show result prime sport. how can I achieve this? Please help me
SELECT *
FROM TABLE
WHERE replace(store_name, ' ', '') LIKE '%'+#SEARCH+'%' OR STORE_NAME LIKE '%'+#SEARCH +'%'
Well, I don't have much idea, and even I am searching for it. But may be what I know works for you, You can achieve this by performing different type of string operations:
Mike can be Myke or Myce or Mikke or so on.
Cat an be Kat or katt or catt or so on.
For this you should write a function to generate number of possible strings and then form a SQL Query using all these, and query the database.
A similar kind of search in known as Soundex Search from Oracle and Soundex Search from Microsoft. Have a look of it. this may work.
And overall make use of functions like upper and lower.
Have you tried using replace()
You can replace the white space in the query then use like
SELECT * FROM table WHERE replace(store_name, ' ', '') LIKE '%primesport%'
It will work for entries like 'prime soft' querying with 'primesoft'
Or you can use regex.