SQL Update conservating actual data - sql

I have a Column named 'Complete name'
I need to update people with any last name 'Smiht' to 'Smith' without losing the name and the second last name.
For example, now I have:
John Smiht G.
Sarah Connor Smiht
John Ford Connor
James Smiht Ford
And the result of update has to be the same data but with Smiht being replaced to Smith:
John Smith G.
Sarah Connor Smith
John Ford Connor
James Smith Ford
Thanks!

The generic method is something like this:
update t
set CompleteName = replace(CompleteName, ' Smiht', ' Smith'
where CompleteName like '% Smiht%';

Related

How do I work with string matching using %?

There is a table that looks like below. I want to match sender's and receiver's names. In this example, I'm only interested in ABC and DEF as their names match (not a complete match but that is ok). How do I extract cases similar to ABC and DEF?
Table A:
id
sender full name
receiver first name
receiver last name
ABC
mike smith brown
mike
smith
DEF
kate josefin baker
kate
baker williams
GHI
kim jones
nathan
wilson

How to continue a sequence when inserting

I have tried to simplify my question with the following example:
I have a table with the following data:
Marker Name Location
1 Eric Benson Mixed
2 John Smith Rural
3 A David Rural
4 B John Mixed
And i want to insert into the table:
Name Location
Andy Jones Mixed
Ian Davies Rural
How can i continue the sequencein the Marker column to end up with:
Marker Name Location
1 Eric Benson Mixed
2 John Smith Rural
3 A David Rural
4 B John Mixed
5 Andy Jones Mixed
6 Ian Davies Rural
If you make this with a Stored Procedure you can ask the max of the Marker before to insert.
(That only works if the Marker Column is not identity)
Like This:
declare #max_marker int
set #max_marker=isnull((select max(marker) from table),0)
--Insert comes here
Insert into table (Marker,Name,Location) Values(#max_marker+1,'Andy Jones','Mixed')

Extract Conditional Middle name and last name

I have a column in a data frame which has a full name as first name, middle name lastname, however for some records no middle name available and want to make sure that it populates the middle name conditionally based on the available pattern but not sure how I can achieve this.
import pandas as pd
name_df = pd.read_csv(r"NameData1.txt",delimiter=",")
splitted_name=name_df.name.str.split(' ',expand=True).fillna('No Value')
##splited_name['middle_name']= splited_name.apply(lambda x : x[1] if x[2] != 'No Value' else '' )
name_df['Middle_name']=name_df.apply(lambda splited_name : splited_name[1] if splited_name[2] != 'No Value' else '')
name_df
I want to display the middle name only when it's there else the last name should be populated.
Sample records:
Id,name
1,TOM M SMITH
2,Gary SMITH
3,John C Doe
4,Hary Knox
5,Rakesh Vaidya
6,John Doe Doe
Use numpy.where for set new column by condition, here are tested None values by Series.isna:
splitted_name=name_df.name.str.split(expand=True)
name_df['First_name'] = splitted_name[0]
name_df['Middle_name']= np.where(splitted_name[2].notna(), splitted_name[1], '')
name_df['Last_name']= np.where(splitted_name[2].notna(), splitted_name[2], splitted_name[1])
print (name_df)
Id name First_name Middle_name Last_name
0 1 TOM M SMITH TOM M SMITH
1 2 Gary SMITH Gary SMITH
2 3 John C Doe John C Doe
3 4 Hary Knox Hary Knox
4 5 Rakesh Vaidya Rakesh Vaidya
5 6 John Doe Doe John Doe Doe
I want to display middle name only wen its there else last name should be populated.
So you can do the below using str.split():
df['middle_or_last']=df.name.apply(lambda x:x.split(' ', maxsplit=len(x.split()))).str[1]
print(df)
Id name middle_or_last
0 1 TOM M SMITH M
1 2 Gary SMITH SMITH
2 3 John C Doe C
3 4 Hary Knox Knox
4 5 Rakesh Vaidya Vaidya
5 6 John Doe Doe Doe

appropriate method for text match in one column to other column in oracle

I have to write a query in Oracle. I have a table called 'Entity' with 2 columns 'Pref_mail_name' and 'spouse_name'.
Now i want list of all spouse_name where the last name of the spouse_name is not populated from pref_mail_name.
For example my table has following data
Pref_mail_name spouse_name
Kunio Tanaka | Lorraine
Mrs. Betty H. Williams | Chester Williams
Mr. John Baranger | Mrs. Cathy Baranger
William kane Gallio | Karen F. Gallio
Sangon Kim | Jungja
i need output as 1st and 5th row only. I did some analysis and came up with oracle built in function
SELECT PREF_MAIL_NAME, SPOUSE_NAME, UTL_MATCH.JARO_WINKLER_SIMILARITY(a, b)
similarity from entity
order by similarity;
But above query is not looking genuine.Even though spouse last name is not populated from pref_mail_name its giving a value above 80 for similarity.

duplicate fields with an inner join

I'm having trouble understanding how to do a multi-table join without generating lots of duplicate fields.
Let's say that I have three tables:
family: id, name
parent: id, family, name
child: id, family, name
If I do a simple select:
select family.id, family.name from family
order by family.id;
I get a simple list:
ID Name
1 Smith
2 Jones
3 Wong
If I add an inner join:
select family.id, family.name, parent.first_name, parent.last_name
from family
inner join parent
on parent.family = family.id
order by family.id;
I get some duplicated fields:
ID Name Parent
1 Smith Howard Smith
1 Smith Janet Smith
2 Jones Phil Jones
2 Jones Harriet Jones
3 Wong Billy Wong
3 Wong Rachel Wong
And if I add another inner join:
select family.id, family.name, parent.first_name, parent.last_name
from family
inner join parent
on parent.family = family.id
inner join child
on child.family = family.id
order by family.id;
I get even more duplicated fields:
ID Name Parent Child
1 Smith Howard Smith Peter Smith
1 Smith Howard Smith Sally Smith
1 Smith Howard Smith Fred Smith
1 Smith Janet Smith Peter Smith
1 Smith Janet Smith Sally Smith
1 Smith Janet Smith Fred Smith
2 Jones Phil Jones Mark Jones
2 Jones Phil Jones Melissa Jones
2 Jones Harriet Jones Mark Jones
2 Jones Harriet Jones Melissa Jones
3 Wong Billy Wong Mary Wong
3 Wong Billy Wong Jennifer Wong
3 Wong Rachel Wong Mary Wong
3 Wong Rachel Wong Jennifer Wong
What I would prefer, because it's more human readable, is something like this:
ID Name Parent Child
1 Smith Howard Smith Peter Smith
Janet Smith Sally Smith
Fred Smith
2 Jones Phil Jones Mark Jones
Harriet Jones Melissa Jones
3 Wong Billy Wong Mary Wong
Rachel Wong Jennifer Wong
I know that one of the benefits of an inner join is to avoid presenting excess information through a Cartesian product. But it seems that I get something similar with a multi-table join. Is there a way to summarize each group as shown above or will this require post-processing with a scripting language like Python?
Thanks,
--Dan
This is precisely the way the relation databases work: each row must contain all information in itself, with every single field that you request. In other words, each row needs to make sense in isolation from all other rows. If you do a single query and you need to get all three levels of information, you need to deal with eliminating duplicates yourself for the desired formatting.
Alternatively, you can run three separate queries, and then do in-memory joins in code. Although this may be desirable in certain rare situations, it is generally a wrong way of spending your development time, because RDBMS are usually much more efficient at joining relational data.
You've hit it on the head. You'll need some post processing to get the results you're looking for.
SQL query results are always simple tabular data, so to get the results you're looking for would definitely not be a pretty query. You could do it, but it would involve quite a bit of query voodoo, storing things in temporary tables or using cursors, or some other funky workaround.
I'd definitely suggest using an external application to retrieve your data and format it appropriately from there.
ORMs like Entity Framework in .NET can probably do this pretty easily, but you could definitely do this with a few nested collections or dictionaries in any language.