Update a single column in a row when value is NULL - sql

I'm having some trouble trying to figure out how to Update a singular cell in a record using SQLPLUS. In a table called CUSTOMER I, the CUSTOMER_NUMBER column is not a Primary Key and is also a null value. I mistakenly made two of the CUSTOMER NUMBER values the same.
My question now, is there any way to ALTER and UPDATE a singular cell in a record? I need to change the Adams row to 412 instead of 522.

This is why primary keys are important!
You have to be VERY CAREFUL to update on another (hopefully unique) field, or you might update more records than expected. Since Adams, Sally appears twice in your example, the street name does differ though for the 522 entry that you mention.
This assumes, of course, that there is only ONE address with this name!
(and that there is not another "16 ELM" in the table that might not appear in your example output)
Try: UPDATE CUSTOMER set CUS=412 WHERE STREET='16 ELM'
If there are other entries having the same address, then those would also get updated. If you had instead used WHERE LAST='Adams', then you would have updated 2 records.

update customer
set cus = 412
where rowid not in (select max(rowid) from customers group by cus);
This should serve your purpose. Please provide a feedback on the outcome.

Related

Excluding data pairs from a query based on a table?

I have a massive and messy database of facilities where there are many duplicates. Addresses have been entered in such a haphazard way that I will be making many queries to identify possible duplicates. My objective is for each query to identify the possible duplicates, and then a person actually goes through the list and marks each pairing as either "not a duplicate" or "possible duplicate."
When someone marks a facility pair as not a duplicate, I want to record that data pair in a table so when that when one of the queries would otherwise return that pairing, it is instead excluded. I am at a loss for how to do this. I'm currently using MS Access for SQL queries, and have rudimentary visual basic knowledge.
Sample of how it should work
Query 1 is run to find duplicates based on city and company name. It brings back that facilities 1 and 2, 3 and 4, 5 and 6 are possible duplicates. The first two pairings are duplicates I need to go fix, but that 5 and 6 are indeed separate facilities. I click to record that facilities 5 and 6 are not duplicates, which records the data in a table. When query 1 is run again it does not return that 5 and 6 are possible duplicates.
For reference, the address duplicates look something like this, which is why there need to be multiple queries
Frank's Garage, 123 2nd St
Frank's Garage LLC, LLC, 123 Second st
Frank's Garage and muffler, 123 2nd Street
Frank's, 12 2nd st
The only way I know to fix this is to create a master table of company names and associate this table PK with records in original table. It will be a difficult and tedious process to review records and eliminate duplicates from master and associate remaining PK of a duplicate group to the original records (as you have discovered).
Create a master table of DISTINCT company and address data from original table. Include autonumber field to generate key. Join tables on company/address fields and UPDATE a field in original table with this key. Have another field in original table to receive a replacement foreign key.
Have a number field (ReplacementPK) in master table. Sort and review records and enter the key you want to retain for company/address duplicates group. Build a query joining tables on original key fields, update NewFK field in original table with selected ReplacementPK from master.
When all looks good:
Delete company and address and original FK fields from original table.
Delete records from master where PK does not match ReplacementPK.

How do I increase 1 value over multiple rows?

I have a item tax table that records the different tax rates for different counties in our state. Each row has an ID number (1-130). Our front end software always orders the tax options by this number when we want it alphabetical. Most of our rows were added that way but I want to be able to insert rows.
Thus I need to add 1 to every entry after a certain number (e.g. 37-130 need to all increase by one). Unfortunately, this is the primary key. Is it possible to increase this value on all of them easily? Or in a loop? I'll have to do this repeatedly as we're moving about a dozen entries if possible.
UPDATE ItemTax
SET ID = ID + 1
WHERE ID = Last ID number
Treating your question as academic, and not endorsing this as an actual solution, you can do this:
UPDATE ItemTax
SET ID = ID + 1
WHERE ID > 37
Depending upon how you use this id, it might be better to leave original ID column unchanged. E.g.
alter table TaxItem add NewID int null
GO
update TaxItem set NewID =
case
when ID between 37 and 130 then ID + 1
else ID
end
Now you don't have to update foreign key relationships, etc.
You see, as ID usually represents a surrogate key, and should never have its value changed in a good design. So your desire to change it value leads to suspicion that you do not understand your design as well as you should. -- We all start from ignorance, I have bad some very poor decisions in the past.
If this is the only change there will ever be for NewID, you don't even need a physical column, a computed column would serve well. But if this is the first mod of many a physical column is likely a better choice.
You also mention inserting rows. Build in some room to insert rows and change values as needed because you have room to rearrange rows by tweaking values without having to renumber entire blocks of rows just to insert a single row, e.g.
update TaxItem set NewID = ID * 100

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

Finding a string it split strings

I'm having a column "SelectedCustomers" in the database table holding selected customers that manager is editing there details NOW. For example it can contain this string '111,222,333' which means that at this current time the manager is selected to edit customers with these ids 111,222 and 333. If another manager is trying to edit a customer that already editing by the first manager the second manager should get an error, preventing him from editing this customer. This check should hold at the sql. And lets say that checking store procedure getting a nvarchard "CheckCustomers" with this value : '234,222,341'. And because the second manager is trying to edit customer with id 222 that is already selected for editing by the first manager. The second manager will get an error message. How should the sql query should be? (I have already a "split" function.)
SELECT * FROM dbo.test WHERE dbo.Split(SelectedCustomers)IN (CheckCustomers)
Why not simply add another column 'IsBeingEdited' in the customer's table? You can then simply:
SELECT id FROM customer WHERE id IN (CheckCustomers) AND IsBeingEdited = 1;
The list shows id's of customer currently being edited, right (and easily changable to other column like name)? So you can also shows that to the 2nd manager.
You can do this with CROSS APPLY.
IF EXISTS (
SELECT S.CustomerID
FROM dbo.test T
CROSS APPLY dbo.Split(T.SelectedCustomers) S
CROSS APPLY dbo.Split(T.CheckCustomers) C
WHERE S.CustomerID = C.CustomerID
)
BEGIN
RAISERROR('Customer is locked by another user', 16, 0)
END
I suggest that this design be changed. Any time do something like splitting strings to get at the 'hidden' fields inside the string is necessary it's a violation of one of the basic principles of using a relational database, which is that each field in a row should store a single value. Can this be made to work? Probably. Is it a good idea to do so? Not in my opinion.
As others have pointed out there are several ways to change the design. A column could be added to the Customer table to indicate that the customer is locked. A separate table (CustomerLocked, for example) containing the CustomerID and the manager's ID could be used - this would allow additional information to be added such as the time that the customer was locked, etc, which might be useful if someone were to lock a customer and then walk away from their desk.
I believe that either of these changes would satisfy the requirements. For example, let's say that a LockedCustomer table is created:
Table LockedCustomer
CustomerID NUMBER PRIMARY KEY
ManagerID VARCHAR
AddDate DATE
and let's say that manager A has locked customers 111, 222, and 333; thus in the LockedCustomer table the following rows would exist:
CustomerID ManagerID
111 A
222 A
333 A
Now along comes manager B, who wishes to lock customer 222. The application manager B is using attempts to insert a new row into the LockedCustomer table, as follows:
INSERT INTO LockedCustomer (CustomerID, ManagerID)
VALUES (222, 'B');
This statement should fail because CustomerID 222 already exists in the table, and the CustomerID column is the primary key on LockedCustomer. This makes sense as we only want a given CustomerID to exist at most one time in the LockedCustomer table at any point in time. The application manager B is using could then detect that the INSERT failed due to a primary key constraint violation, and would understand that this meant that the customer could not be locked at this time. By re-querying the LockedCustomer table for additional data, as in:
SELECT *
FROM LockedCustomer
WHERE CustomerID = 222
the application could present a dialog to Manager B that might look something like
The customer you wished to edit (222) is currently in use
by Manager A since 03-Jun-2011 2:17 PM. Would you like to
A) Wait
B) Send an email to Manager A
C) Take a long vacation
D) Violate company policy regarding alcohol consumption
during working hours
Please select one of the above options?
Share and enjoy.

Moving and Deleting rows in MySQL

I have created two tables in MySQL which are called "birthTable" and "deathTable". When I add a person in deathTable which she/he was in birthTable, I want to delete his/her name and family from birthtable because I add him/her in deathTable. But I don't know how I can do that?
What you describe can be done manually or with triggers, but generally you should not do it.
You should have a table called people, and then simply mark them as dead or alive. Instead, you may also create two columns for their birthday and deathday, if you intend to store this information.
In general, you shouldn't be moving records simply because some attribute about them has changed.
This is the SQL:
DELETE FROM birthTable WHERE id = ...
where id is the name of some identifying field.
Here is the documentation for DELETE.
What you have to do is construct a DELETE FROM-query. If you only want to delete one row from a table, you need to be certain that the parameters you give it are unique for that row. Usually this is done by having a column called id. Then, knowing the id, all you have to do is this:
DELETE FROM table WHERE id=<your id>;
I think that in your case you could just have a table called "people", and a boolean column "alive" which is 1 if the person is alive and 0 if the person is dead.
If you still want to delete one row from your birthTable, assuming you know the name of this person, you do it like this:
DELETE FROM birthTable WHERE firstName=<first name> AND lastName<last name>;
I've assumed that the column names for first and last names are firstName and lastName, you'll have to modify this to match your column names. This will delete any entry in the birthTable which matches the critera (could be more than one, if you have for example 2 people called Alan Johnson).
Hope that helps. :)
You can write trigger on insert on table deathTable which deletes corresponding row from birthTable.
CREATE TRIGGER trg_deathTable_insert
BEFORE INSERT ON deathTable
FOR EACH ROWS
BEGIN
DELETE FROM birthTable WHERE person_id = NEW.person_id;
END;
DELETE FROM birthTable WHERE id = xxx