MySQL SELECT query string matching - sql

Normally, when querying a database with SELECT, its common to want to find the records that match a given search string.
For example:
SELECT * FROM customers WHERE name LIKE '%Bob Smith%';
That query should give me all records where 'Bob Smith' appears anywhere in the name field.
What I'd like to do is the opposite.
Instead of finding all the records that have 'Bob Smith' in the name field, I want to find all the records where the name field is in 'Robert Bob Smith III, PhD.', a string argument to the query.

Just turn the LIKE around
SELECT * FROM customers
WHERE 'Robert Bob Smith III, PhD.' LIKE CONCAT('%',name,'%')

You can use regular expressions like this:
SELECT * FROM pet WHERE name REGEXP 'Bob|Smith';

Incorrect:
SELECT * FROM customers WHERE name LIKE '%Bob Smith%';
Instead:
select count(*)
from rearp.customers c
where c.name LIKE '%Bob smith.8%';
select count will just query (totals)
C will link the db.table to the names row you need this to index
LIKE should be obvs
8 will call all references in DB 8 or less (not really needed but i like neatness)

Related

Using Contains how to search for more than one value

Here is what I am trying to do:
select * from Person where CONTAINS((fName,sName),'John AND Doe')
So I am trying to search for John Doe but I get that I cannot use AND here (just showing my chain of thought) so how can I search for John in the fName and Doe in the sName ? But I don't want to use "Contains" twice like this:
SELECT * FROM Person
WHERE CONTAINS((fName), 'John')
AND CONTAINS((sName), 'Doe');
Since we can have
(fName,sName)
but I cannot use
'John','Doe'/'John' AND 'Doe'
Your statement
SELECT * FROM Person
WHERE CONTAINS((fName), 'John')
AND CONTAINS((sName), 'Doe');
can't compile because CONTAINS returns a number, not a boolean.
It shall respond,on oracle, with this kind of error
ORA-00920: opérateur relationnel non valide
00920. 00000 - "invalid relational operator"
(the relational operator error's cause is not the AND's existence, it's because you try to AND two numbers)
What do you intend to do? If you want to select the line in the person table whose fName columns contains the substring John and whose sName column contains the substring Doe, you may use the like operator, which uses % as a wildcard.
SELECT * FROM Person
WHERE fName LIKE '%John%'
and sName LIKE '%Doe%'
I don't practice much the CONTAINS method, but if you desire to use it, according to documentation, you should use something like
SELECT * FROM Person
WHERE CONTAINS(fName, 'John') > 0
and CONTAINS(sName,'Doe') > 0
If you really don't want to use the AND operator (for whatever obscure reason like proving a sql injection filter is bad), you can use this trick : compare a concatenation of the 2 columns and the like operator like so
SELECT * FROM Person
WHERE fName || sName like '%John%Doe%';
but this last trick will also match the line where fname is John Doe and sName is Jean-Michel :)
This should work:
SELECT * FROM dbo.Person
WHERE CONTAINS((fName), 'John')
AND CONTAINS((sName), 'Doe');
But in your case you dont want to use 2 contains so:
Alternatively, you could add a new computed column with a full text index on it.
Add a column like this:
computedCol AS fName+ ' ' + sName
And create the full text index:
CREATE FULLTEXT INDEX ON Person(computedCol LANGUAGE 1033)
KEY INDEX pk_Person_yourPrimaryKeyName
Then you can do this:
SELECT * FROM dbo.Person
WHERE CONTAINS(*, 'John AND Doe')
Hope it works.

How can I bring a register only if it doesn't contains a string - SQL?

My query is something like this:
SELECT * FROM table WHERE name LIKE "%Mary%"
But now, I want bring all the occurrences as long as it's not contains "Jane" especially in "Mary". I do not want "Mary Jane", neither "Jane Mary" or any variation (e.g. "Mary Smith Jane").
I really don't know how to.
EDIT:
I'm not sure if I can only use a "not like" because I'm already using "not like" in the same query for other reasons.
In fact:
SELECT * FROM table WHERE name NOT LIKE "%John%"
AND name NOT LIKE '%Charlie%'
AND name LIKE '%Mary%'
Just add that to the WHERE clause:
WHERE name LIKE '%Mary%' AND
name NOT LIKE '%Mary Jane%'
Or, if you mean that the exact match is not what you want:
WHERE name LIKE '%Mary%' AND
name <> 'Mary Jane'
SELECT *
FROM your_table
WHERE name LIKE '%Mary%'
and name <> 'Mary Jane'
In order to retrieve records that contain Mary in the string, but not Jane, you will want to keep your clause for LIKE '%Mary%' and add a clause for NOT LIKE '%Jane%'.
You can group these clauses together with parenthesis in order to isolate them from other clauses in the query.
SELECT *
FROM table
WHERE
(name LIKE '%Mary%'
AND name NOT LIKE '%Jane%')

selecting with a column being one of two possible values

I have a table called "people" with a column named "name". I would like to select all rows where the name is "bob" or "john". I have tried the following and many variants of it, none of which work. How can I do this correctly?
select * from people where name is bob or john;
Thanks
To compare a column with a value you need to use = not IS
select *
from people
where name = 'bob'
or name = 'john';
Alternatively you can use the IN operator.
select *
from people
where name IN ('bob','john');
Note that string comparison is case-sensitive in SQL. So the above will not return rows where the name is Bob or John

Updating table where LIKE has several criteria

I have two tables in PostgreSQL (version 9.3). The first holds id, title and the second holds schdname. I'm trying to create a select statement that will retrieve id and title where the title contains the schdname from the other table. The id, title table can hold several thousand rows. I can do this fine if I use WHERE LIKE for an individual schdname example but there are 40 plus names so this is not practical.
My original query ran like this which I know doesn't work but would show what I'm trying to achieve.
SELECT
id,
title,
dname
FROM
mytable
WHERE
title LIKE (
SELECT
schdname
FROM
schedule
)
This produces an error of more than one row returned by the subquery used as an expresssion. So my question is can this be achieved another way?
Here is one way to do that:
SELECT id, title, dname FROM mutable
JOIN schedule ON mutable.title like '%' || schedule.schdname || '%'
Or a sligtly more readable way:
SELECT id, title, dname FROM mutable
JOIN schedule ON POSITION(schedule.schdname in mutable.title)<>0
Are you actually using a wildcard with like? You don't say so above. If not you can replace like with IN. If you do want to do a wildcard join I'd recommend taking a substring of the columns and comparing that e.g.
names
james
jack
janice
select substr(names,1,2) as names_abbr
from names_table where names_abbr = (select ...)

SQL BETWEEN not working properly

I am using Microsoft SQL Server
I am trying to use the following sql command to get the records between First_Name "Nilsen" and "Ram"
select * from persons where First_Name between 'Nilsen' and 'Ram'
but i am getting the output as two records with first names "nilsen" and "ram"; not the records between these records.
In another command, i tried doing similar thing with Last names.
select * from persons where Last_Name between 'Johan' and 'Chandra'
this command shows just a blank persons table.
Please tell me its not working properly.
This query:
SELECT *
FROM persons
WHERE First_Name between 'Nilsen' and 'Ram'
will return all entries with First_Name alphabetically between Nilsen and Ram (like Oscar, Rachel or Norbert)
This query:
SELECT *
FROM persons
WHERE Last_Name between 'Johan' and 'Chandra'
will never return anything since Johan is greater than Chandra (i. e. goes later in alphabetical order).
Update:
Just a wild guess: if you want to match something like Nilsen Hermenegild J. P. Ram, Jr., you need to use this:
SELECT *
FROM persons
WHERE FirstName LIKE '%Nilsen%Ram%
This is how BETWEEN works, from MSDN
BETWEEN returns TRUE if the value of
test_expression is greater than or
equal to the value of begin_expression
and less than or equal to the value of
end_expression.
so
select * from persons where First_Name between 'Nilsen' and 'Ram'
should return records with first names 'Nilsen' and 'Ram', plus the records between.
Just guessing, try this:
select * from persons where lower(First_Name) between 'nilsen' and 'ram'