Separate Columns with conditions - mysql

I have a table with some problem data. For example, the table is as follow :
ID NAME JOB
--- --------------------------- ---------------
1 Peter Teacher
2 John Programmer
3 Tom**He is a Teacher
4 Alan**He is a Accountant
The problem is some data has been correctly inserted but some hasn't. Now I want to execute an SQL in order to make the table looks like below :
ID NAME JOB
--- --------------------------- ---------------
1 Peter Teacher
2 John Programmer
3 Tom Teacher
4 Alan Accountant
I am not familiar with SQL Statement so I can just think of using the following PHP Script to fix this problem.
$sql1 = "SELECT NAME FROM MY_TABLE WHERE JOB = '' AND NAME LIKE '%He is a %'";
$res1 = mysql_query($sql1);
while($row1 = mysql_fetch_array($res1)){
$new_data = explode("**He is a ", $row1["NAME"]);
$sql2 = "UPDATE MY_TABLE SET NAME = '".$data[0]."', JOB = '".$data[1]."' WHERE ID = '".$data["ID"]."'";
mysql_query($sql2);
}
Can anyone suggest a better way for me to fix this problem with one or a few SQL Statement ? Thanks

UPDATE
SET NAME = SUBSTRING_INDEX(SUBSTRING_INDEX(NAME, '**He is a ', 1), ' ', -1),
job = SUBSTRING_INDEX(SUBSTRING_INDEX(NAME, '**He is a ', 2), ' ', -1)
WHERE NAME LIKE '%**He is a %'

You can use the substring_index function to break up the string, and apply all the changes in a single update statement:
UPDATE my_table
SET JOB = SUBSTRING_INDEX (name, '**He is a ', -1),
name = SUBSTRING_INDEX (name, '**He is a ', 1),
WHERE name LIKE '%**He is a %' AND
(job IS NULL OR job = '') -- Just to be on the safe side

Related

MysQL Update if a count condition is met

I have a table which consists of 5000 rows. I need SQL command that could update each row by removing all values in "(...)" if only one couple of () is found.
Basically, if I have a name in a row:
Name surname (extra info)
I need to remove "(extra info)" and leave only Name surname
But if there is no additional couple of ()
If there is a row
Name Surname(data) (extra info)
The script should not amend this name
In simple words, I need to update a name where is only one ( or ) symbol
Many thanks
can you try to find first '(' and substring to it ?
don't forget to use case for none ( in string
update userlogin
set fullname = case position('(' in FullName)
when 0
then fullname
else substring(Fullname,1,position('(' in FullName) - 1)
end
This is an implementation of my question. I used select to let me check the result before applying it to update request. The script shows a table of
3 columns: Id, Name, UpdatedName, where Name is what we have and UpdatedName what we will obtain
SELECT `Id`,`Name`,
(case when ((LENGTH(`Name`)-LENGTH(REPLACE(`Name`, '(', ''))) = 1)
THEN
SUBSTRING_INDEX(`Name`, '(', 1)
ELSE
'-'
END)
as updated_name,
FROM table
WHERE (LENGTH(`Name`)-LENGTH(REPLACE(`Name`, '(', ''))) = 1
LIMIT 0,1500
P.S. I used Id to allow me to amend values
SELECT CASE
WHEN fname = 'correct' THEN 'your condition'
WHEN sname = 'correct' THEN 'your second condition'
ELSE 'baz'
END AS fullname
FROM `databasetable`
or you can do as like also
CASE
WHEN action = 'update' THEN
UPDATE sometable SET column = value WHERE condition;
WHEN action = 'create' THEN
INSERT INTO sometable (column) VALUES (value);
END CASE

How can I extract a last name from full name in mysql?

I have a table with fullname column. I want to make a query for finding a person via his last name but his last name is in the full name column.
Would it matter if it accidentally returned someone whose first name matched your query?
A simple query would be:
SELECT *
FROM TABLE
WHERE fullname LIKE '%insertlastname%'
If you want to define the last name as the name after the last space:
SELECT substring_index(fullname, ' ', -1) as lastname
FROM TABLE
WHERE lastname='insertlastname'
Two suboptimal answers, but some answers at least.
enter code here You can use this if you want to fetch by query:
SELECT SUBSTRING_INDEX(SUBSTRING_INDEX( `fullname` , ' ', 2 ),' ',1) AS b,
SUBSTRING_INDEX(SUBSTRING_INDEX( `fullname` , ' ', -1 ),' ',2) AS c FROM `users` WHERE `userid`='1'
But you can also try by PHP to fetch last name. You just use explode function to fetch last name.
Exm:
$full_name = "row moin";
$pieces = explode(" ", $fullname);
echo $first_name = $pieces[0]; // row
echo $last_name = $pieces[1]; // moin
A simple answer for this is like this suppose we have a name
Charles Dickens
:
SELECT * FROM TABLE_NAME WHERE SUBSTRING_INDEX(FULLNAME,' ',-1) like '%Dickens';

Is there a way for switch 2 words in MySQL row field

I would want to switch 2 words (firstName lastName) in a mysql row's fields
example :
I have a column 'persons' with a field :
Jonh Smith
I would want to switch to : Smith Jonh
I searched a lot for a MySQL function or snippet but found no way.
Try this update if the field has only two words
UPDATE tablename
SET persons = CONCAT(SUBSTRING_INDEX(SUBSTRING_INDEX(persons, ' ', 2), ' ', -1),' ',
SUBSTRING_INDEX(SUBSTRING_INDEX(persons, ' ', 1), ' ', -1))

Splitting a single column (name) into two (forename, surname) in SQL

Currently I'm working on a database redesign project. A large bulk of this project is pulling data from the old database and importing it into the new one.
One of the columns in a table from the old database is called 'name'. It contains a forename and a surname all in one field (ugh). The new table has two columns; forenames and surname. I need to come up with a clean, efficient way to split this single column into two.
For now I'd like to do everything in the same table and then I can easily transfer it across.
3 columns:
Name (the forename and surname)
Forename (currently empty, first half of name should go here)
Surname (currently empty, second half of name should go here)
What I need to do: Split name in half and place into forename and surname
If anyone could shed some light on how to do this kind of thing I would really appreciate it as I haven't done anything like this in SQL before.
Database engine: MySQL
Storage engine: InnoDB
A quick solution is to use SUBSTRING_INDEX to get everything at the left of the first space, and everything past the first space:
UPDATE tablename
SET
Forename = SUBSTRING_INDEX(Name, ' ', 1),
Surname = SUBSTRING_INDEX(Name, ' ', -1)
Please see fiddle here. It is not perfect, as a name could have multiple spaces, but it can be a good query to start with and it works for most names.
Try this:
insert into new_table (forename, lastName, ...)
select
substring_index(name, ' ', 1),
substring(name from instr(name, ' ') + 1),
...
from old_table
This assumes the first word is the forename, and the rest the is lastname, which correctly handles multi-word last names like "John De Lacey"
For the people who wants to handle fullname: John -> firstname: John, lastname: null
SELECT
if( INSTR(`name`, ' ')=0,
TRIM(SUBSTRING(`name`, INSTR(`name`, ' ')+1)),
TRIM(SUBSTRING(`name`, 1, INSTR(`name`, ' ')-1)) ) first_name,
if( INSTR(`name`, ' ')=0,
null,
TRIM(SUBSTRING(`name`, INSTR(`name`, ' ')+1)) ) last_name
It works fine with John Doe. However if user just fill in John with no last name, SUBSTRING(name, INSTR(name, ' ')+1)) as lastname will return John instead of null and firstname will be null with SUBSTRING(name, 1, INSTR(name, ' ')-1).
In my case I added if condition check to correctly determine lastname and trim to prevent multiple spaces between them.
This improves upon the answer given, consider entry like this "Jack Smith Smithson", if you need just first and last name, and you want first name to be "Jack Smith" and last name "Smithson", then you need query like this:
-- MySQL
SELECT
SUBSTR(full_name, 1, length(full_name) - length(SUBSTRING_INDEX(full_name, ' ', -1)) - 1) as first_name,
SUBSTRING_INDEX(full_name, ' ', -1) as last_name
FROM yourtable
Just wanted to share my solution. It also works with middle names. The middle name will be added to the first name.
SELECT
TRIM(SUBSTRING(name,1, LENGTH(name)- LENGTH(SUBSTRING_INDEX(name, ' ', -1)))) AS firstname,
SUBSTRING_INDEX(name, ' ', -1) AS lastname
I had a similar problem but with Names containing multiple names, eg. "FirstName MiddleNames LastName" and it should be "MiddleNames" and not "MiddleName".
So I used a combo of substring() and reverse() to solve my problem:
select
SystemUser.Email,
SystemUser.Name,
Substring(SystemUser.Name, 1, instr(SystemUser.Name, ' ')) as 'First Name',
reverse(Substring(reverse(SystemUser.Name), 1, instr(reverse(SystemUser.Name), ' '))) as 'Last Name',
I do not need the "MiddleNames" part and maybe this is not the most efficient way to solve it, but it works for me.
Got here from google, and came up with a slightly different solution that does handle names with more than two parts (up to 5 name parts, as would be created by space character). This sets the last_name column to everything to the right of the 'first name' (first space), it also sets full_name to the first name part. Perhaps backup your DB before running this :-) but here it is it worked for me:
UPDATE users SET
name_last =
CASE
WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 1)) = LENGTH(full_name) THEN ''
WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 2)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -1)
WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 3)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -2)
WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 4)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -3)
WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 5)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -4)
WHEN LENGTH(SUBSTRING_INDEX(full_name, ' ', 6)) = LENGTH(full_name) THEN SUBSTRING_INDEX(del_name, ' ', -5)
ELSE ''
END,
full_name = SUBSTRING_INDEX(full_name, ' ', 1)
WHERE LENGTH(name_last) = 0 or LENGTH(name_last) is null or name_last = ''
SUBSTRING_INDEX didn't work for me in SQL 2018, so I used this:
declare #fullName varchar(50) = 'First Last1 Last2'
declare #first varchar(50)
declare #last varchar(50)
select #last = right(#fullName, len(#fullName)-charindex(' ',#fullName, 1)), #first = left(#fullName, (charindex(' ', #fullName, 1))-1);
Yields #first = 'First', #last = 'Last1 Last2'

Reformat table data sql

I have a field name with the following rows:
`name`
------
John Smith
George Washington
Ash Ketchum
Bill O'Reilly
I would like to reformat the rows on output:
`name`
------
SMITH, JOHN
WASHINGTON, GEORGE
KETCHUM, ASH
O'REILLY BILL
I know I can use upper( x.name ) for casing, but how can I reformat the names?
Assuming your rdbms is mySql, answer will need to be tailored to differenct dialects of sql.
SELECT concat( substring(name, locate(name, ' ')), ', ', substring(name, 0, locate(name, ' ') - 1)) FROM NAMES;
The real problem here however is data integrity. You need to have seperate columns for each peice of the name so that formating in the database is ensured to be consitent. Ideally you would want to be doing this --
Select concat(last_name, ', ', first_name) FROM NAMES;
Allowing
'name'
-------------------
John Smith
Smith, John
J Smith
Smith J
John q Smith
Jhon 'the smithmeister' Smith
All in the same column of a table is a bad thing for a number of reasons so this should be explictly prevented.
Try this:
SELECT SUBSTRING_INDEX( `name` , ' ', -1 ) + ', ' + SUBSTRING_INDEX( `name` , ' ', 1 )
FROM MyTable
#Ben, makes a good point about names with multiple spaces in them. I doubt this would give you the output you want in those cases, but it should get you started.
try this
SELECT Concat(SUBSTRING_INDEX( `name` , ' ', -1 ) , ', ' , SUBSTRING_INDEX( `name` , ' ', 1 )) as name
FROM your_Table