Select only when the field has more than one word - sql

SELECT name FROM clients;
Table clients
id | name |
1 John
2 John Bravo
3 John Alves
4 Jo
In postgres, how can I select only names with more than one word? For example. This should be the output:
John Bravo
John ALves

I think just test if the name contains a space: where name like '% %'
But this will give you some problem if you name can contain space char befor or after the name, like: ' JOHN' or 'Luck '

If word means to you a space delimited token, then the following would do the trick:
SELECT name FROM clients WHERE name LIKE '% %';
But this will also give you those that have empty names made out of spaces only. Also performance-wise, this will be a costly query.

First you may have to find the number of words in the column, then only select where the number of words is greater than 1.
For example:
SELECT LENGTH(name) - LENGTH(REPLACE(name , ' ', ''))+1 FROM clients;
This will return the number of words in each row, which we have in the field name.
Then you can proceed putting this in a nested select SQL statement something like :
SELECT LENGTH(name) - LENGTH(REPLACE(name, ' ', ''))+1 as mycheck, name FROM clients where (SELECT LENGTH(name) - LENGTH(REPLACE(name, ' ', ''))+1)>1
This will return only where words are greater than 1 (>1). Else you can user >2 to return columns with more than 2 words.

LIKE is an option, or you can use split_part:
SELECT name FROM clients WHERE split_part(trim(name), ' ', 2) <> ''

Related

How to return 0 with where condition user when user search only space character?

Hello I'm using Oracle 11g and i have a data that looks like this
no|name|flag
------------
1|kumar|1
2|rajesh singh|1
3|adi sneedar|1
4|danielle castro|1
5|cef danish|1
if i did
select count(*) from tablename where name like '% %'
it will return 2 records.
if i did "multiple spaces", like 2 or more spaces
select count(*) from tablename where name like '% %'
it returns 0(this means good)
it will return 5 records.
What i want is if the user only input '% %' it will also return 0. But i also wanted that
select count(*) from tablename where name like '%adi sneedar%'
it will return 1
How should i do that in the where condition?
Something like this might suffice, assuming that the '%' are being passed as part of the binding input
select *
from mytable
where name like :bindvar
and replace(replace(:bindvar,'%'),' ') is not null
which basically says they need to enter something that is not solely spaces and percentage signs.

how to skip particular character(s) in SQL LIKE query

I have a table(say users) in which there is a column say name.
you may think table structure a shown below:
-------------
name
--------------
Abdul Khalid
--------------
Abdul, Khalid
--------------
Abdul - Khalid
--------------
other names
My question is can I do some query to find all the 3 rows in which the name column value is "Abdul Khalid"(basically "Abdul Khalid" or "Abdul, Khalid" or "Abdul - Khalid" if I skip the "," and "-" character).
You can use like:
select t.*
from t
where name like 'Abdul%Khalid';
If you want the names anywhere in the string (but in that order), then put wildcards at the beginning:
select t.*
from t
where name like '%Abdul%Khalid%';
If you are passing in the value as a variable:
select t.*
from t
where name like replace('Abdul Khalid', ' ', '%');
For PostgreSQL is better to use '~'
name ~ '^Abdul[ ,-]Khalid$'
OR if you want also in middle of string:
name ~ 'Abdul[ ,-]Khalid'
Or you can use translate (with index on it) for any SQL:
translate(name, ' ,-') = 'AbdulKhalid'
you also can use REGEXP like this:
SELECT * from yourTable where name REGEXP 'Abdul( |, | - )Khalid';

Changing LastName,FirstName to LastName,FirstInitial

I'm sure this is super easy, but how would I go about converting LastName,FirstName to LastName,FirstInitial?
For example changing Smith,John to Smith,J or Johnson,John to Johnson,J etc.
Thank You!
In case of LastName and FirstName columns:
select LastName,substr(FirstName,1,1)
from mytable
;
In case of a fullname saved in a single column:
select substr(fullname,1,instr(fullname || ',',',')-1) || substr(fullname,instr(fullname || ',',','),2)
from mytable
;
or
select regexp_replace (fullname,'([^,]*,?)(.).*','\1\2')
from mytable
;
Here is one way, using just "standard" instr and substr. Assuming your input is a single string in the format 'Smith,John':
select substr(fullname, 1, instr(fullname, ',')+1) from yourtable;
yourtable is the name of the table, and fullname is the name of the column.
instr(fullname, ',') finds the position of the comma within the input string (it would be 6 in 'Smith,John'); thensubstrtakes the substring that begins at the first position (the1in the function call) and ends at the position calculated byinstr`, PLUS 1 (to get the first initial as well).

Oracle SQL - See if Value Contains Substrings from Three Other Values

I have three columns for a person's name (first middle last) and a column for a user ID.
The purpose of this code is to find persons with a UserID that does not match their name.
The UserID is created by taking the FIRST letter of the first name, the FIRST letter of the middle name and the FULL last name. Mary Jane Smith would have the UserID of MJSmith34. Random numbers are added to the end when there is more than one MJSmith, but this does not matter for what I need.
The code below compares the person's last name in two areas. If they do not match, it means that the person's name has been changed. What I need now is to check the UserID against the most current First Middle Last name to see if the UserID need to be changed (updated). The Pseudocode is what I need, but I am not sure if it can even be done. Please help!!
Select DISTINCT
NL.spriden_id as "STU_ID",
NL.SPRIDEN_LAST_NAME as "Last_Name" ,
NL.SPRIDEN_FIRST_NAME as "First_Name"
FROM SARADAP SA
JOIN SPRIDEN NM -- NM is Name
ON SA.SARADAP_PIDM = NM.SPRIDEN_PIDM
JOIN SPRIDEN NL -- NL is null
ON SA.SARADAP_PIDM = NL.SPRIDEN_PIDM
JOIN IDTABLE ID
ON ST.SOMETABLE_PIDM = ID.IDTABLE_PIDM =
WHERE
NM.SPRIDEN_CHANGE_IND LIKE '%N%'
AND
NL.SPRIDEN_CHANGE_IND IS NULL
AND
NL.SPRIDEN_ACTIVITY_DATE between sysdate - 10 and sysdate
AND
NL.spriden_id LIKE 'A00%'
AND
lower(NL.SPRIDEN_LAST_NAME) <> lower(NM.SPRIDEN_LAST_NAME)
AND
NL.SPRIDEN_ACTIVITY_DATE <> NM.SPRIDEN_ACTIVITY_DATE
Pseudocode -
I know I need something with the POSITION of the characters.
I need help making this pseudocode into real code, please! :)
AND ID.USERID LIKE '%(NL.SPRIDEN_LAST_NAME)%'
AND SUBSTRING (1st CHAR OF ID.USERID) LIKE
SUBSTRING FIRST CHARACTER OF (NL.SPRIDEN_FIRST_NAME)
AND SUBSTRING (2nd char of ID.USERID) LIKE
SUBSTRING FIRST CHAR OF (NL.SPRIDEN_MIDDLE_NAME)
AND ID.USERID LIKE SUBSTR(NL.SPRIDEN_FIRST_NAME, 1, 1)
|| SUBSTR(NL.SPRIDEN_MIDDLE_NAME, 1, 1)
|| NL.SPRIDEN_LAST_NAME || '%'
|| is a concatenation operator
This condition means: check if USERID starts with the first symbol SPRIDEN_FIRST_NAME + the first symbol of SPRIDEN_MIDDLE_NAME + SPRIDEN_LAST_NAME
A slight variation on Multisync's good answer:
AND REGEXP_LIKE(ID.USERID, SUBSTR(NL.SPRIDEN_FIRST_NAME, 1, 1)
|| SUBSTR(NL.SPRIDEN_MIDDLE_NAME, 1, 1)
|| NL.SPRIDEN_LAST_NAME || '[0-9]*$', 'i')
-- ^
-- case insensitive compare
That way you won't have false positive for cases such as James Tiberius Kirk => jtkirkwood and you get case insensitive compare "for free".
The drawback here is I assume you don't have regex special characters as part of the name of your users...
Think about normalizing case too!

how to split a column into multiple value using sql

If I have thousands of rows with data and I would like to find out if the column called "Last
Name " contains both First Name and Last Name (could be middle initial too). What SQL command
do I use ? (SQL Server 2008). Once I find it, how do I split the Last Name field and place
first name or middle initial in their own columns ?
For example:
First Name MI Last Name
John B. Smith
Karen A. Jones
Jane Lawrence
Joan K. Bates
Could it be done in Excel as well ?
You could look for spaces in the last name:
select *
from t
where lastname like '% %';
You could look for rows where the first name is missing:
select *
from t
where firstname is null or firstname = '';
EDIT:
If we assume that the names are "simple" as given in the sample data, you can do:
update t
set firstname = left(lastname, charindex(' ', lastname) - 1),
lastname = right(lastname, charindex(' ', reverse(lastname))),
mi = (case when lastname like '% % %'
then rtrim(ltrim(substring(lastname, charindex(' ', lastname + 1), 2)))
end)
where lastname like '% %' and firstname is null;
This makes lots of assumptions about the formats . . . that there are no complete middle names, that there are no honorics, that there are no suffixes, that there are no multiple spaces together. But if your data is simple, it should work.
Here is an example of the logic in SQL Fiddle.
I would do it in two passes:
-- Set first name
UPDATE names
SET FirstName = SUBSTR(LastName,1,CHARINDEX(' ',LastName) - 1),
LastName = SUBSTR(LastName,CHARINDEX(' ',LastName) + 1, LEN(LastName))
WHERE FirstNAme IS NULL
AND CHARINDEX(' ',LastName) > 0
-- Set middle name
UPDATE names
SET MI = SUBSTR(LastName,1,CHARINDEX(' ',LastName) - 1),
LastName = SUBSTR(LastName,CHARINDEX(' ',LastName) + 1, LEN(LastName))
WHERE MI IS NULL
AND CHARINDEX(' ',LastName) > 0
You may have a few false positives but that should get the vast majority of cases.
I would STRONGLY recommend creating a transaction, doing the updates, doing a SELECT to see the results and rolling back the transaction since the update is not reversible.