SQL - retrieval query for specific string - sql

I am making a small database at the moment (less than 50 entries) and I am having trouble with a query. My query at the moment is
SELECT Name
FROM Customers
WHERE Name LIKE '%Adam%'
The names are in the format of "Adam West".
The query works fine in retrieving all the people with "Adam" in their name but I would like to only retrieve the first name, not the last name. I don't want to split the columns up but would like to know how to rewrite my query to account for this.

SELECT Name
FROM Customers
WHERE Name LIKE 'Adam%'

if you are storing name with space as separator example "Adam abcd" where 'Adam' is firstname and 'abcd' as lastname then following will work
SELECT Expr1
FROM (SELECT LEFT(Name, CHARINDEX(' ', Name, 1)) AS Expr1
FROM Customers) AS derivedtbl_1
WHERE (Expr1 LIKE 'Adm%')
for more details read this article http://suite101.com/article/sql-functions-leftrightsubstrlengthcharindex-a209089

If the name of your customers starts with first name (like Adam West) you can use
select Name
from Customers
where Name like 'Adam %'
Otherwise, if the format of the name is <last name> <first name> you can use
select Name
from Customers
where Name like '% Adam'

Try this
{SELECT Name
FROM Customers
WHERE SUBSTRING(Name,1,CHARINDEX(' ',Name)-1) LIKE '%Adam%'
}
I assumed the first name and last name is saparated by space and i took the firstname out
Using SUBSTRING(Name,1,CHARINDEX(' ',Name)-1)
and compared how you wanted. if your have something else saparating first name and last name change space in charindex with the saparater.
Please let me know if any other help needed.
Regards
Ashutosh

You should indeed "split" your columns and normalize your tables to avoid having to use complicated string functions to search for a lastname or firstname or what ever you need to look for. What about if someone entered lastname first and then firstname? Or just a nickname?
That said, check the use of LIKE on Microsoft technet site. The following query should be helpful on you case:
SELECT Name
FROM Customers
WHERE Name LIKE 'Adam%'

Related

Count specific column in DB2

I have a table contact with three columns e.g. name, surname and age.
I would like to count the number of entries from the specific column surname.
How looks the select statement in DB2 to achieve this?
You can change the column name using as :
select count(surname) as surname_count
from contact c;
I assume you want to perform a
select count(surname)
from contact
group by surname
but you need to put some effort into the question and prove you have already researched a bit beforehand

Fuzzy Duplicate Finding with SQLite

this is my first post and I'm something of a novice.
I'm trying to extract a list of fuzzy duplicates from and table of company names using SQLite with sqlite3.
For example, for a company like 'ZtPay' I'm currently using:
SELECT name FROM tab WHERE name LIKE 'Z_Pay');
SELECT name FROM tab WHERE name LIKE 'Zt_ay');
etc...
To account for typos.
My problem is that if there is no typo then I just output the original company name. Ideally I would like only to output the original name if there was a fuzzy duplicate found by the LIKE.
I know this is very wrong but I want something along the lines of:
SELECT name FROM tab WHERE name LIKE 'Z_Pay' IF ATLEAST 2 name LIKE 'Z_Pay'
Thanks in advance for any help you can give me.
You can determine if there is more than one name by looking at the min() and max():
SELECT name
FROM tab
WHERE name LIKE 'Zt_ay%'
group by name
having min(name) <> max(name)
Alternatively, you could use count(distinct):
SELECT name
FROM tab
WHERE name LIKE 'Zt_ay%'
group by name
having count(distinct name) > 1;

Geting value count from an Oracle Table

I have a table, that contains employees. Since the company I'm working for is quite big (>3k employees) It is only natural, that some of them have the same names. Now they can be differentiated by their usernames, but since a webpage needs a drop-down with all of these users, I need to add some extra data to their names.
I know I could first grab all of the users and then run them through a foreach and add a count to each of the user objects. That would be quite ineffective though. Therefore I'm in need of a good SQL query, that would do something like this. Could a sub-query be the thing I need?
My Table looks something like this:
name ----- surname ----- username
John Mayer jmaye
Suzan Harvey sharv
John Mayer jmay3
Now what I think would be great, if the query returned the same 3 fields and also a boolean if there is more than one person with the same name and surname combination.
Adding the flag to Daniel's answer...
SELECT NAME, SURNAME, USERNAME, DECODE(COUNT(*) OVER (PARTITION BY NAME, SURNAME), 1, 'N', 'Y')
FROM
YOUR_TABLE;
Please note that Oracle SQL has no support for booleans (sigh...)
This can be easily done with a count over partition:
SELECT NAME, SURNAME, USERNAME, COUNT(*) OVER (PARTITION BY NAME, SURNAME)
FROM
YOUR_TABLE;

SQL wildcard matching excluding a specific pattern

sorry about the question I am a newbie to sql. i am attempting to create a search query for our database and I was wondering how would you filter certain words from your query for example:
Here is the sample data (the name column): Jean, Jain, Joan, Jorn, Juan, John, Juin
Lets say that we are searching for the names that start with "J" and end with "n" but we don't want to include "John".
SELECT id, name
FROM tblusers
WHERE name LIKE 'j__n'
WHERE name NOT LIKE 'John'
Obviously the above will have an error, so I was wondering how do I correctly write the above.
Thanks in advance.
SELECT id, name
FROM tblusers
WHERE name LIKE 'j%n'
AND name NOT LIKE 'John'

Using 'OR' between HAVING and WHERE clause in MySQL?

I am trying to fetch records in MySQL using a simple used submitted field. More precisely, the user inputs a name (firstname or lastname or fullname) and the server should return matched rows.
What I am doing so far is something like:
SELECT * FROM people
WHERE
firstname LIKE '%user_submitted_data%' OR
lastname LIKE '%user_submitted_data%'
That works well for now, but that (obviously) won't work when a user submits the fullname. Is there a way to add a OR between the whole 'WHERE type conditions' and the 'HAVING type conditions'? This way I could do something like:
SELECT [some fields], CONCAT(firstname, ' ', 'lastname') as fullname
FROM people
WHERE
firstname LIKE '%user_submitted_data%' OR
lastname LIKE '%user_submitted_data%' OR
HAVING fullname LIKE '%user_submitted_data%'
I know I could just split the original string but that has some negative impact since you have to deal with names containing spaces such as 'De Gaule' and stuff like that.
Just put all conditions into the HAVING clause.
SELECT [some fields], CONCAT(firstname, ' ', 'lastname') as fullname
FROM people
HAVING firstname LIKE '%user_submitted_data%'
OR lastname LIKE '%user_submitted_data%'
OR fullname LIKE '%user_submitted_data%
The WHERE clause could discard rows early, but since you cannot discard them until after you have evaluated the condition on the computed column, and that has to wait until HAVING, it buys you nothing to use WHERE.
Do a subquery:
SELECT [some fields]
FROM
SELECT firstname, lastname, CONCAT(firstname, ' ', lastname) as fullname
FROM people) AS tmp
WHERE firstname LIKE '%user_submitted_data%'
OR lastname LIKE '%user_submitted_data%'
OR fullname LIKE '%user_submitted_data%'
Let's consider some possible inputs:
John
Smith
John Smith
Your initial sample query is:
SELECT * FROM people
WHERE
firstname LIKE '%user_submitted_data%' OR
lastname LIKE '%user_submitted_data%'
Now, when the user enters the first input, this query will pick all the people whose first name contains 'John'; it will also pick all the people whose last name contains 'John' (for example, all the Johnsons in the database). Similarly, the second input will pick all the people whose first name contains 'Smith'; it will also pick all the people whose last name contains 'Smith' (for example, the Smithsons and Smithers). So far, so good; it isn't perfect because of case-sensitivity issues (I will ignore case-sensitivity from here on, but you probably should not ignore it at all), but it will be OK.
The third input will only pick the people whose first name contains 'John Smith'; it will also pick those people whose last name contains 'John Smith'. However, it is rather likely that there are very few people who meet those criteria - those people called John Smith will have just John in the first name and just Smith in the last name. This is unlikely to be what you had in mind.
It is not clear whether you have a column called 'fullname' in the table. If you do, then you can just match against that column instead of matching against the first name and last name separately. If you don't, maybe you can manufacture such a column and then run the query against that.
SELECT *
FROM (SELECT firstname || ' ' || lastname AS fullname, ... FROM people) AS t
WHERE t.fullname LIKE '%user_submitted_data%'
This works reasonably well.
However, if you are worried about names such as 'Charles De Gaulle' (or 'Charles de Gaulle') or 'Michael van den Berg'), then the matching will fail if someone enters 'Charles Gaulle' or 'Michael Berg', let alone Michael Vandenberg. You would probably need to replace any space characters in the user input with a '%' symbol too. Even then, you face the problem that the words must appear in exactly the sequence given by the user - which may not matter, but you should consciously decide that it doesn't matter. For example, if the input is 'Adam John Smith', then the query won't catch 'John Adam Smith'; if the input is 'Smith, John', then it won't pick up anyone (most likely).
If you want to manage this, you probably need to tokenize the user's input, and search on the separate words. Beware of someone asking about a sub-string of a word (for example, someone asks about 'de' as a name word) - none of the queries at the moment ensures that the user input words match whole words in the values (John vs Johnson), and doing so with the SQL standard LIKE operator is near enough impossible.
You can reference a computed column in the WHERE clause if you define that column in a subquery:
SELECT p.*
FROM (
SELECT [some fields], CONCAT(firstname, ' ', 'lastname') as fullname
FROM people
) p
WHERE
p.firstname LIKE '%user_submitted_data%' OR
p.lastname LIKE '%user_submitted_data%' OR
p.fullname LIKE '%user_submitted_data%';
But honestly, for the type of search you're doing, LIKE with wildcards is a terrible solution. You should think about using a FULLTEXT index:
CREATE FULLTEXT INDEX people_names ON people(firstname, lastname);
SELECT *
FROM people
WHERE MATCH(firstname, lastname) AGAINST( ? );
PS: FULLTEXT indexes work only with the MyISAM storage engine. Another solution, even more speedy, is to use Sphinx Search for fulltext indexing.
Although using a subquery works well, it will have an impact because you are not hitting any indexes.
What about adding a computed column (firstname || ' ' || lastname) to the table and an index to it? Surely it would be much faster.
If you cannot do that I think that querying like
WHERE firstname || ' ' || lastname LIKE '%user_submitted_data%'
should still work faster than two ORs and one subquery.