Compare strings in SQL - sql

I am in a situation where I need to return results if some conditions on the string/character are met.
For example: to return only the names that contain 'F' character from the Person table.
How to create an SQL query based on such conditions? Is there any link to a documentation that explains how can SQL perform such queries?
Thanks in advance

The most basic approach is to use LIKE operator:
-- name starts with 'F'
SELECT * FROM person WHERE name LIKE 'F%'
-- name contains 'F'
SELECT * FROM person WHERE name LIKE '%F%'
(% is a wildcard)

Most RDBMS offer string operations which are able to perform that required task in one way or the other.
In MySQL you might use INSTR:
SELECT *
FROM yourtable
WHERE INSTR(Person, 'F') > 0;
In Oracle, this can be done, too.
In PostgreSQL, you can use STRPOS:
SELECT *
FROM yourtable
WHERE strpos(Person, 'F') > 0;
Usually there are several approaches to solve this, many would choose the LIKE operator. For more details, please refer to the documentation of the RDBMS of your choice.
Update
As requested by the questioner a few words about the LIKE operator, which are used not only in MySQL or Oracle, but in other RDBMS, too.
The use of LIKE will in some cases make your RDBMS try to use an index, it usually does not not try to do so if you use a string functions.
Example:
SELECT *
FROM yourtable
WHERE Person LIKE 'F%';

The query may look like this:
SELECT * FROM Person WHERE FirstName LIKE '%F%' OR LastName LIKE '%F%'

Related

Using CONTAINS to find items IN a table

I'm trying to write a SP that will allow users to search on multiple name strings, but supports LIKE functionality. For example, the user's input might be a string 'Scorsese, Kaurismaki, Tarkovsky'. I use a split function to turn that string into a table var, with one column, as follows:
part
------
Scorsese
Kaurismaki
Tarkovsky
Then, normally I would return any values from my table matching any of these values in my table var, with an IN statement:
select * from myTable where lastName IN (select * from #myTableVar)
However, this only returns exact matches, and I need to return partial matches. I'm looking for something like this, but that would actually compile:
select * from myTable where CONTAINS(lastName, select * from #myTableVar)
I've found other questions where it's made clear that you can't combine LIKE and IN, and it's recommended to use CONTAINS. My specific question is, is it possible to combine CONTAINS with a table list of values, as above? If so, what would that syntax look like? If not, any other workarounds to achieve my goal?
I'm using SQL Server 2016, if it makes any difference.
You can use EXISTS
SELECT * FROM myTable M
WHERE
EXISTS( SELECT * FROM #myTableVar V WHERE M.lastName like '%'+ V.part +'%' )
Can your parser built the entire statement? Will that get you what you want?
select *
from myTable
where CONTAINS
(lastName,
'"Scorsese" OR "Kaurismaki" OR "Tarkovsky"'
)
This can be done using CHARINDEX function combined with EXISTS:
select *
from myTable mt
where exists(select 1 from #myTableVar
where charindex(mt.lastName, part) > 0
or charindex(part, mt.lastName) > 0)
You might want to omit one of the conditions in the inner query, but I think this is what you want.

Create table - SQL Oracle

I need to create table, which should I call Others. I want only employeers who names which having names start with any other letter, but not K
I wrote sthg like this:
CREATE TABLE others AS select * from employees WHERE last_name no like 'K%';
I found sthg like this idea but it doesn't work
I'm receiving errror about syntax. Can you help me?
The second question: there is any other way to write it?
Try This
CREATE TABLE others AS (SELECT *
FROM employees
WHERE last_name NOT LIKE 'K%');
As #jarlh said in his comment, a view would serve the same purpose, but the data would only be stored once instead of twice, thus saving disk space. You could define the view as
CREATE OR REPLACE VIEW OTHERS AS
SELECT *
FROM EMPLOYEES
WHERE LAST_NAME NOT LIKE 'K%';
Best of luck.
I would recommend using just string functions. Here are two ways:
WHERE SUBSTR(last_name, 1, 1) <> 'K'
or:
WHERE last_name < 'K' or last_name >= 'L'
Although you can use LIKE or REGEXP_LIKE() for this, I like this simpler approaches.

sql In clause with wildcards (DB2)

Is there anyway to use wildcards in a clause similar to a "in", like this
select * from table where columnx xxxxxxx ('%a%','%b%')?
I know I can do:
select * from table where (columnx like '%a%' or columnx like '%b%')
But I'm looking for an alternative to make the querystring shorter.
BTW: I'm not able to register any custom functions, nor temp tables, it should be a native DB2 function.
I found this similar answer for oracle and SQLServer:
Is there a combination of "LIKE" and "IN" in SQL?
There's no native regular expression support in "pureSQL" for DB2, you can either create your own as in:
http://www.ibm.com/developerworks/data/library/techarticle/0301stolze/0301stolze.html
or use pureXML as in: http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.xml.doc/doc/xqrfnmat.html
Example:
where xmlcast(xmlquery('fn:matches(\$TEXT,''^[A-Za-z 0-9]*$'')') as integer) = 0
Yet another variant that may be shorter:
select t.*
from table t
join ( values '%a%', '%b%' ) u (columnx)
on t.columnx like u.columnx

SQL inline conditional in Select

I was wondering if something like this was possible:
SELECT name or alt_name FROM users Where userid=somenum
I have also tried this:
SELECT name IF NOT NULL ELSE alt_name ...
If anyone has any insight I'd appreciate it.
If your trying to replace nulls then
select coalesce(name,alt_name)....
it will return first non null value
How about this?
SELECT IsNull(name, alt_name) FROM users Where userid=somenum
Its similar to the Coalesce function, but it only takes two arguments and is easier to spell.
Do you mean something like this? I'm assuming TSQL
SELECT CASE WHEN [name] IS NOT NULL THEN [name] ELSE [alt_name] END AS [UserName]
FROM [Users] WHERE [UserId] = somenum
Not the most efficient answer, but what about this:
SELECT name FROM users WHERE userid=somenum AND name IS NOT NULL
UNION
SELECT altname FROM users WHERE userid=somenum AND name IS NULL
I think this will produce what you are after.
SELECT CASE
WHEN userid = somenum THEN name
ELSE alt_name
END
FROM users
If you're using a database that supports them then one of the simplest ways is to use a user defined function, you'd then have
SELECT udfPreferredName() FROM users
where udfPreferredName() would encapsulate the logic required to choose between the name and alternative_name fields.
One of the advantages of using a function is that you can abstract away the choice logic and apply it in multiple SQL statements wherever you need it. Doing the logic inline using a case is fine, but will usually be (much) harder to maintain across a system. In most RDBMS the additional overhead of the function call will not be significant unless you are handling very large tables

Is there any way to combine IN with LIKE in an SQL statement?

I am trying to find a way, if possible, to use IN and LIKE together. What I want to accomplish is putting a subquery that pulls up a list of data into an IN statement. The problem is the list of data contains wildcards. Is there any way to do this?
Just something I was curious on.
Example of data in the 2 tables
Parent table
ID Office_Code Employee_Name
1 GG234 Tom
2 GG654 Bill
3 PQ123 Chris
Second table
ID Code_Wildcard
1 GG%
2 PQ%
Clarifying note (via third-party)
Since I'm seeing several responses which don't seems to address what Ziltoid asks, I thought I try clarifying what I think he means.
In SQL, "WHERE col IN (1,2,3)" is roughly the equivalent of "WHERE col = 1 OR col = 2 OR col = 3".
He's looking for something which I'll pseudo-code as
WHERE col IN_LIKE ('A%', 'TH%E', '%C')
which would be roughly the equivalent of
WHERE col LIKE 'A%' OR col LIKE 'TH%E' OR col LIKE '%C'
The Regex answers seem to come closest; the rest seem way off the mark.
I'm not sure which database you're using, but with Oracle you could accomplish something equivalent by aliasing your subquery in the FROM clause rather than using it in an IN clause. Using your example:
select p.*
from
(select code_wildcard
from second
where id = 1) s
join parent p
on p.office_code like s.code_wildcard
In MySQL, use REGEXP:
WHERE field1 REGEXP('(value1)|(value2)|(value3)')
Same in Oracle:
WHERE REGEXP_LIKE(field1, '(value1)|(value2)|(value3)')
Do you mean somethign like:
select * FROM table where column IN (
SELECT column from table where column like '%%'
)
Really this should be written like:
SELECT * FROM table where column like '%%'
Using a sub select query is really beneficial when you have to pull records based on a set of logic that you won't want in the main query.
something like:
SELECT * FROM TableA WHERE TableA_IdColumn IN
(
SELECT TableA_IdColumn FROM TableB WHERE TableA_IDColumn like '%%'
)
update to question:
You can't combine an IN statement with a like statement:
You'll have to do three different like statements to search on the various wildcards.
You could use a LIKE statement to obtain a list of IDs and then use that in the IN statement.
But you can't directly combine IN and LIKE.
Perhaps something like this?
SELECT DISTINCT
my_column
FROM
My_Table T
INNER JOIN My_List_Of_Value V ON
T.my_column LIKE '%' + V.search_value + '%'
In this example I've used a table with the values for simplicity, but you could easily change that to a subquery. If you have a large list (like tens of thousands) then performance might be rough.
select *
from parent
where exists( select *
from second
where office_code like trim( code_wildcard ) );
Trim code_wildcard just in case it has trailing blanks.
You could do the Like part in a subquery perhaps?
Select * From TableA Where X in (Select A from TableB where B Like '%123%')
tsql has the contains statement for a full-text-search enabled table.
CONTAINS(Description, '"sea*" OR "bread*"')
If I'm reading the question correctly, we want all Parent rows that have an Office_code that matches any Code_Wildcard in the "Second" table.
In Oracle, at least, this query achieves that:
SELECT *
FROM parent, second
WHERE office_code LIKE code_wildcard;
Am I missing something?