update column, table-normalization - sql

i have a table like:
name
location
Emma
Athens
Nick
Berlin
Emma
Athens-Greece
Nick
Berlin, Germany
Emma
233 Street, Athena
Nick
Berlin's
at first, i want to change all values like '%Athen%' to 'Athens' and the same for Berlin
my problem is that my table is full of values like that and it's big , so i wonder if there is a way to do it faster without writing every city-case, such as using functions like substring or creating a function with general forms of my data.
I mean that i don't want something like:
update Person set city='Athens' where city like '%Athen%'
i have to have one name for the same city because, about the above example, it's the same emma who lives in athens and the same nick who lives in berlin, so i have to normalize my table to see only one time each person from each city.

I don't believe there is a simple solution that means you don't have to check every value. The way I would do it would be:
Create a distinct list of every unique location value
Put this distinct list in column 1 of a 2 column "lookup" table
In the second column put the "clean" version of the value in column 1
Write a query that will update the values in your source table based on the values in your lookup table
Having the data in a table, rather in some form of complex SQL CASE statement, makes the information much easier to maintain and the SQL to update your source table much simper

Related

Insert one of a pair of values into SQL table based on matching value of other

I'm having a hard time searching for this, and if this question has already been asked and answered I will gladly use that information.
I have a table that is basically complete. But I need to change the values of one column in that I have in a text file. The text file has paired values. One matches an existing value in another column of the table, the other is the new value I need to use to replace the old value in the table.
So for example I have stuff like this in the table:
Name Address
John Smith 123 Main St
Jim Brown 123 Main St
Bob Jones 123 Main St
And in the text file I have:
John Smith;123 Real Address
Jim Brown;456 Another Real Address
Bob Jones;789 Yet Another Address
I want to be able to match on the name and insert each matching address into the table. Can I do this in a big query? Perhaps an update with a join to a selected set of values like this:
UPDATE MyTable
SET Name = (SELECT **all my values here**)
WHERE Name = **something**
Or maybe it would be possible to export the entire table, and merge the values in a text file with a script, then reinsert the new table values? I can't figure out a convenient way to do this though.
Use SSIS or any tool you prefer to import the text file to a separate table, and then UPDATE your existing table with a JOIN to the new table.
There are already plenty of questions on the site that answer the question of how to UPDATE a table with a JOIN to another table. Here is a good one:
How can I do an UPDATE statement with JOIN in SQL?

Coalesce SQL output when one field has multiple values

I am trying to create a list of emergency contacts for students in our school district. I would like to include their names and phone numbers. The phone number field in the database has multiple phone numbers stored for each student.
So if I run the following query :
Select name, number
From student
My Results look like this (I'm using made up numbers and names):
Alex A. 235-777-8888
Alex A. 235-777-8878
Alex A. 235-777-8899
Sarah B. 435-777-9999
Sarah B. 435-777-9988
What I would like my result to look like would be:
Alex A. 235-777-8888, 235-777-8878, 235-777-8899
Sarah B. 435-777-9999, 435-777-9988
Basically I just want each student name listed once followed by all of the numbers associated with them.
Any suggestions? I am pretty new to both SQL and programming in general, so the simpler the solution the better!

SQL Create Field based on Other Field in Record

I would like to create a field in my sql query based on the data in another field. For example:
First Name Last Name Hometown State (created column based on Hometown)
Phil Smith Brooklyn NY
Bill Jones Manhattan NY
Abraham Phillips Cleveland OH
Michael Davis Cincinnati OH
William Brett Queens NY
The "State" column could come from a look-up table or in an if / else statement. I'm not sure how to do this, so I would appreciate any help.
This is one "solution", there are many more.
You could create one table called "Person" consisting of FirstName, LastName and Hometown (I presume you may have that table already) and a lookup table called "CityToState" with City and State.
Fill the lookup table with appropriate data (it'll be quite large, I'm sure) and issue the query
select FirstName, LastName, Hometown, State
from Person left join CityToState on Hometown=City;
That should give you the correct data, with NULL returned for the state if the city does not exist in the lookup table.
Basically what this does is to get all data from Person and join it, row by row with the row in CityToState where HomeTown is the same as City. The "left" part means that it should return the row from the left table (Person) even if there is no matching row in CityToState.
look up computed column for the database you are using (which you do not state in the question). Here is info on SQL Server's Computed Columns.
However, I think you should use a different design. If you are looking up the state based on the hometown, a foreign key is enough, no need to duplicate the data.

sql cross reference table

I amy trying to build a statistics table for marketing issues for specific site :
currently I planning to build table like this
Source_IP source_city Destination_IP destination_city
127.0.0.1 NY 242.212.12.1 Paris
242.212.12.1 Paris 127.0.0.1 NY
I want to prevent case like the above I.E the combination of (Source_ip , source_city) and (Destination_IP destination_city) should only be one record and not 2 how can i prevent this on sql?
Assuming your DBMS allows function based indexes, the following would do the trick:
CREATE UNIQUE INDEX idx_no_dupes
ON your_table (least(source_ip, destination_ip), greatest(source_ip, destination_ip));
The use of least and greatest will always index the tuples in the "same order", so it doesn't matter which value is in which column.
If your DBMS does not support least or greatest you will need to replace this with a CASE construct.
For MS SQL Server you could implement a check constraint
My first idea was, well, a first idea. So, there are better suggestions here, but another possibility, though probably not a great one, is to implement a trigger on insert or update to first search the table to make sure that those items don't exist elsewhere. If none is found, then the trigger allows the action, otherwise, it rolls back. Like I said, not great, but a possibility.
normalize your table ...
take one table for locations containing a location ID, the ip, and the city name
and have a 2nd table where you can put pairs of location ids a location id and a pair id ...
example:
table 1:
Location
ID IP City
1 127.0.0.1 Ny
2 242.212.12.1 Paris
table 2:
Pairs
ID Location
1 1
1 2

How to remove unwanted rows and create new column in SQL?

I have two tables.
My first table is called as WORLD and this table have a column named PEOPLE. In PEOPLE table I have both women's and men's names.
My second table is called as MEN and this table has a column named NAMES. It consists of men's names.
What I want to do is by comparing those two tables finding women's names and adding them to a column named "WOMEN" in the WORLD table.
WORLD.PEOPLE MEN.NAMES
John John
Joe Alan
Jessica Michael
Martin Martin
Alan Adam
Eva Joe
Mary
What I want to have is:
WORLD.PEOPLE WORLD.WOMEN
John Jessica
Joe Eva
Jessica Mary
Martin
Alan
Eva
Mary
I tried using this statement:
SELECT People FROM WORLD WHERE (People NOT IN(SELECT Names FROM MEN)))
However this only gives result, it doesn't update the WORLD table.
What should I do?
You should try to Create a new table and add the values there and then drop the WORLD table.
I guess you just want to work on one single database, but i can't think any other easier way. With insert you will get null values so it won't be practical. You can try what i said.
You must have some key field in table WORLD for identification records.
Or use another table for store women names.
INSERT INTO world(women) SELECT People FROM WORLD WHERE (People NOT IN(SELECT Names FROM MEN)))
or something like that?
Also, see the documentation.
I'm not sure if the above syntax is correct, because you're inserting data to a table by selecting data from the same table. Maybe you need to use "AS".