Use string contains function in oracle SQL query - sql

I'm using an Oracle database and I want to know how can I find rows in a varchar type column where the values of that column has a string which contains some character.
I'm trying something like this (that's a simple example of what I want), but it doesn't work:
select p.name
from person p
where p.name contains the character 'A';
I also want to know if I can use a function like chr(1234) where 1234 is an ASCII code instead of the 'A' character in my example query, because in my case I want to search in my database values where the name of a person contains the character with 8211 as ASCII code.
With the query select CHR(8211) from dual; I get the special character that I want.
Example:
select p.name
from person p
where p.name contains the character chr(8211);

By lines I assume you mean rows in the table person. What you're looking for is:
select p.name
from person p
where p.name LIKE '%A%'; --contains the character 'A'
The above is case sensitive. For a case insensitive search, you can do:
select p.name
from person p
where UPPER(p.name) LIKE '%A%'; --contains the character 'A' or 'a'
For the special character, you can do:
select p.name
from person p
where p.name LIKE '%'||chr(8211)||'%'; --contains the character chr(8211)
The LIKE operator matches a pattern. The syntax of this command is described in detail in the Oracle documentation. You will mostly use the % sign as it means match zero or more characters.

The answer of ADTC works fine, but I've find another solution, so I post it here if someone wants something different.
I think ADTC's solution is better, but mine's also works.
Here is the other solution I found
select p.name
from person p
where instr(p.name,chr(8211)) > 0; --contains the character chr(8211)
--at least 1 time
Thank you.

You used the keyword CONTAINS in your sample queries and question. CONTAINS lets you search against columns that have been indexed with an Oracle*Text full-text index.
Because these columns are full-text indexed, you can efficiently query them to search for words and phrases anywhere with the text columns without triggering a full table scan. Depending upon their usage, using LIKE or INSTR will almost always result in a full table scan.
CONTAINS is used to search for words and phrases. Although there are many options it is not appropriate if you are looking for embedded characters such as 'A' or chr(8211).
The following query will return all rows that contain the word "smith" anywhere in their text.
SELECT score(1), p.name
FROM person p
WHERE CONTAINS(p.name, 'smith', 1) > 0;
For more details see:
How does contains() in PL-SQL work?
Oracle SQL "contains" clause tips
Oracle: Contains Documentation
Oracle: Contains Operators

Just in case you need you need to find if a column has any values that have character in it, you can use regexp_like. The first parameter is the column name to be checked and the second parameter is the regular expression.
If the below sql returns count greater than zero, that means there are some row(s) in which there is 1 or more character in it.
SELECT COUNT(*)
FROM TABLE_NAME
WHERE regexp_like (COLUMN_NAME, '[^0-9]')

Related

SQL: Return records containing a word where the last letter is anything except K

Suppose I have a table containing a column by the name "Query". I have to display the records where the string in this column has used noloc instead of nolock. Note that noloc can be followed/preceded by ) or space etc. I just need all records that have anything before and after noloc except nolock. Is there a way to do it in SQL?
I tried:
select * from table1
where Query LIKE '%noloc%'
but this includes queries containing nolock. I tried variations of the above like putting space before and/or after % but none of them fills all the criteria.
You can use both conditions in the where clause
select * from table1
where Query LIKE '%noloc%' and Query NOT LIKE '%nolock%'
You want anything + noloc + any one char but k + anything. Here:
select * from table1
where Query LIKE '%noloc[^k]%'

SQLite query to get distinct columns

I am trying to write a query where I need to check whether a value is not present in an array of strings returned by another nested query how can I do that,
For example I have to check whether,
1234 is present in [abc_1234,fgh_12345,ghi_5343]
Hence 1234 is present in string abc_1234 so I will not select 1234.
I hope I understand your request correctly. You have a query returning strings, e.g. 'abc_1234' and 'fgh_12345'. You have a table with values, e.g. '1234'. You want to select rows from the table where the value is not part of any of the strings of the existing query.
This is where the anti-join pattern comes into play. You outer-join the undesired rows, so all rows that found no partner are the desired ones:
select *
from mytable m
left join (<your query here>) q on instr(q.string, m.value) > 0
where q.string is null;
(Instead of INSTR you can also use LIKE: on q.string like '%' || m.value || '%'. It should not matter which of the string operations you choose.)

Oracle SQL: how to search honorofics in a string

I have name fields in my data set. Using Oracle PL SQL, how can I search for the records that contain honorifics?
I have a list of honorifics that I want to search for in a separate table.
Any help would be really appreciated.
Thanks.
I'd use REGEXP_LIKE and do a cross join against the honorifics table.
This query will list all names that have an honorific, plus the honorific. If a name has more than one honorific it will be listed for each match:
SELECT
myTable.Name,
honorifics.Title
FROM myTable
CROSS JOIN honorifics
WHERE REGEXP_LIKE(myTable.Name, ''(\W|^)' || honorifics.Title || '(\W|$)')
The regex checks to see if the honorific title is at the beginning of the string or preceded by a "non-word" character, and if it's at the end of the string or followed by a non-word character.
Note that this search is case sensitive. To make it non-case sensitive, add a third argument of 'i' to the REGEXP_LIKE:
WHERE REGEXP_LIKE(myTable.Name, ''(\W|^)' || honorifics.Title || '(\W|$)', 'i')
^^^^^
SELECT names.lastName
FROM names
INNER JOIN honorophics ON names.lastName LIKE honorophics.listOfHonorophics + '%'
this will join the 2 tables, resulting in the rows, where lastName contains a pattern from the table with honorophics

Wildcards in sql

How does wildcards works in sql. If I do select * from table it give all the fields. But if I do select a* from table it gives error. Shouldn't it give all fields which begins with a?
I am little confused.
SELECT * FROM tableName literally means "select all columns from tableName".
Philip Graham is right about his answer where he asked to use a.*
Wildcards help you search for strings about which you are not sure. These are almost always used with the LIKE keyword and put in WHERE clauses or searched CASE statements.
There are two wildcard characters - % and _.
% is used to find any string of 0 or more length.
E.g.,
SELECT firstName
FROM persons
WHERE UPPER(firstName) LIKE 'J%'
This will return all the firstName from the persons table where firstname starts with letter J. This would return "Jason", "James", "Josh", "Jessica" and much more.
Note that UPPER function was used to eliminate case sensitivity.
Next, you can have an _ character that looks for the presence of one single character.
SELECT firstName
FROM persons
WHERE UPPER(firstName) LIKE 'J_M__'
This would return "James", "Jimmy", "Jamos", "Jxmx" and filter away any "Jason", "Jaguar", etc.
For more info click here
You can use a.* where a is the name of the table. For instance in
select a.* from a left join b on a.id = b.id
You would return only the fields from a but not from b
If want to use a wild card in SQL, You need to key on the column that you want to filter using LIKE.
SELECT *
FROM table
WHERE column_name LIKE 'a%';
This will give you everything that begins with 'a' on that column.
If you don't want all the columns, you must explicitly give the name of each column that you want in the query.
SELECT LastName, FirstName, Address
FROM table
So if you want all the fields that begin with 'a' you must name all the fields that begin with 'a' in the SELECT statement.
Hope this helps.

SQL Joining with Imperfect Match

Is it possible to match the following combination of such keys in SQL?
The key values like an array and delimiter = '/'.
Key
-----
A/B/C
A
B
C
A/B
A/C
B/C
My first thought to you is that you need to redesign. You should not store data that way. You should have a related table instead. Then you can do ordinary joins to get what you want. Rule 1 of database design is to store only one piece of information per field. If you are finding you need to break this down into smaller chunks than you are storing, you are storing incorrectly.
Some of the proposed solutions will work (depending on what you are really asking which is not clear) but most if not all of them will be slow as they rely on syntax which will not alow you to use indexes. This is one major reason why a redesign is indicated. You do not want a system where the indexes can't be used.
Assuming here your keys are single letters as in your example, you could use LIKE:
SELECT * FROM table WHERE key LIKE '%A%'
Would give you all the values where "key" contains "A".
SELECT *
FROM mytable
WHERE `key` REGEXP '^([ABC]/)*[ABC]?$'
This will match anything from above, but will not match if there are other letters (like D/B/C or AA/BB/CC)
You will be better off using REGEXP
SELECT * FROM table WHERE key REGEXP '[[:<:]]A[[:>:]]'
[[:<:]] and [[:>:]] mark a word boundry, this will stop 'A' matching AB,AC,AD
I'm not sure if they are mysql specific
What database?
If dealing with Oracle, I suggest using INSTR
For SQL Server: CHARINDEX
mySQL also uses INSTR
Use any of those to test for a value greater than zero.
SELECT t.*
FROM TABLE t
WHERE INSTR(t.column, expectedValue) > 0
You haven't stated your problem very clearly. I'm taking it that this list of keys conceptually rep ordered sets, and you want to find all possible subset / superset combinations (e.g. I think you want 'A/C' to "match" 'A/B/C').
This seems to work but I'd be hard pressed to prove that the logic is right:
SELECT a.key subset, b.key superset
FROM key_list a, key_list b
WHERE '/' || REPLACE( b.key, '/', '//') || '/'
LIKE '/' || REPLACE( a.key, '/', '/%/' ) || '/'
OR b.key LIKE '%' || a.key || '%'
ORDER BY length(a.key), a.key, length(b.key),b.key