SQL Script: Updating a column with another table pivoting on an ID - sql-server

I have two SQL Server tables: ORDERS and DELIVERIES.
I would like to update the ORDERS table with a value from DELIVERIES. The ORDERS PK (OrderID) is common to both tables. Also, I would like to restrict the action to a specific CustomerID (within ORDERS).
ORDERS table:
OrderID | AccountID | AnalysisField1
DELIVERIES table:
DeliveryID | OrderID | AddressName
I want to update ORDERS.AnalysisField1 with the value from DELIVERIES.AddressName (linked by OrderID) but only where ORDERS.AccountID = '12345'
Please help. JM

Then try to use something like this:
UPDATE dbo.Orders
SET AnalysisField1 = d.Addressname
FROM dbo.Deliveries d
WHERE
d.OrderID = dbo.Orders.OrderID
AND dbo.Orders.AccountID = '12345'
If your AccountID column is of a numerical type (which the ID suffix would suggest), then you should not put unnecessary single quotes around the value in the WHERE clause:
AND dbo.Orders.AccountID = 12345

Related

How to add data to a single column

I have a question in regards to adding data to a particular column of a table, i had a post yesterday where a user guided me (thanks for that) to what i needed and said an update was the way to go for what i need, but i still can't achieve my goal.
i have two tables, the tables where the information will be added from and the table where the information will be added to, here is an example:
source_table (has only a column called "name_expedient_reviser" that is nvarchar(50))
name_expedient_reviser
kim
randy
phil
cathy
josh
etc.
on the other hand i have the destination table, this one has two columns, one with the ids and the other where the names will be inserted, this column values are null, there are some ids that are going to be used for this.
this is how the other table looks like
dbo_expedient_reviser (has 2 columns, unique_reviser_code numeric PK NOT AI, and name_expedient_reviser who are the users who check expedients this one is set as nvarchar(50)) also this is the way this table is now:
dbo_expedient_reviser
unique_reviser_code | name_expedient_reviser
1 | NULL
2 | NULL
3 | NULL
4 | NULL
5 | NULL
6 | NULL
what i need is the information of the source_table to be inserted into the row name_expedient_reviser, so the result should look like this
dbo_expedient_reviser
unique_reviser_code | name_expedient_reviser
1 | kim
2 | randy
3 | phil
4 | cathy
5 | josh
6 | etc.
how can i pass the information into this table? what do i have to do?.
EDIT
the query i saw that should have worked doesn't update which is this one:
UPDATE dbo_expedient_reviser
SET dbo_expedient_reviser.name_expedient_reviser = source_table.name_expedient_reviser
FROM source_table
JOIN dbo_expedient_reviser ON source_table.name_expedient_reviser = dbo_expedient_reviser.name_expedient_reviser
WHERE dbo_expedient_reviser.name_expedient_reviser IS NULL
the query was supposed to update the information into the table, extracting it from the source_table as long as the row name_expedient_reviser is null which it is but is doesn't work.
Since the Names do not have an Id associated with them I would just use ROW_NUMBER and join on ROW_NUMBER = unique_reviser_code. The only problem is, knowing what rows are null. From what I see, they all appear null. In your data, is this the case or are there names sporadically in the table like 5,17,29...etc? If the name_expedient_reviser is empty in dbo_expedient_reviser you could also truncate the table and insert values directly. Hopefully that unique_reviser_code isn't already linked to other things.
WITH CTE (name_expedient_reviser, unique_reviser_code)
AS
(
SELECT name_expedient_reviser
,ROW_NUMBER() OVER (ORDER BY name_expedient_reviser)
FROM source_table
)
UPDATE er
SET er.name_expedient_reviser = cte.name_expedient_reviser
FROM dbo_expedient_reviser er
JOIN CTE on cte.unique_reviser_code = er.unique_reviser_code
Or Truncate:
Truncate Table dbo_expedient_reviser
INSERT INTO dbo_expedient_reviser (name_expedient_reviser, unique_reviser_code)
SELECT DISTINCT
unique_reviser_code = ROW_NUMBER() OVER (ORDER BY name_expedient_reviser)
,name_expedient_reviser
FROM source_table
it is not posible to INSERT the data into a single column, but to UPDATE and move the data you want is the only way to go in that cases

T-SQL Select, manipulate, and re-insert via stored procedure

The short version is I'm trying to map from a flat table to a new set of tables with a stored procedure.
The long version: I want to SELECT records from an existing table, and then for each record INSERT into a new set of tables (most columns will go into one table, but some will go to others and be related back to this new table).
I'm a little new to stored procedures and T-SQL. I haven't been able to find anything particularly clear on this subject.
It would appear I want to something along the lines of
INSERT INTO [dbo].[MyNewTable] (col1, col2, col3)
SELECT
OldCol1, OldCol2, OldCol3
FROM
[dbo].[MyOldTable]
But I'm uncertain how to get that to save related records since I'm splitting it into multiple tables. I'll also need to manipulate some of the data from the old columns before it will fit into the new columns.
Thanks
Example data
MyOldTable
Id | Year | Make | Model | Customer Name
572 | 2001 | Ford | Focus | Bobby Smith
782 | 2015 | Ford | Mustang | Bobby Smith
Into (with no worries about duplicate customers or retaining old Ids):
MyNewCarTable
Id | Year | Make | Model
1 | 2001 | Ford | Focus
2 | 2015 | Ford | Mustang
MyNewCustomerTable
Id | FirstName | LastName | CarId
1 | Bobby | Smith | 1
2 | Bobby | Smith | 2
I would say you have your OldTable Id to preserve in new table till you process data.
I assume you create an Identity column Id on your MyNewCarTable
INSERT INTO MyNewCarTable (OldId, Year, Make, Model)
SELECT Id, Year, Make, Model FROM MyOldTable
Then, join the new table and above table to insert into your second table. I assume your MyNewCustomerTable also has Id column with Identity enabled.
INSERT INTO MyNewCustomerTable (CustomerName, CarId)
SELECT CustomerName, new.Id
FROM MyOldTable old
JOIN MyNewCarTable new ON old.Id = new.OldId
Note: I have not applied Split of Customer Name to First Name and
Last Name as I was unsure about existing data.
If you don't want your OldId in MyNewCarTable, you can DELETE it
ALTER TABLE MyNewCarTable DROP COLUMN OldId
You are missing a step in your normalization. You do not need to duplicate your customer information per vehicle. You need three tables for 4th Normal form. This will reduce storage size and more importantly allow an update to the customer data to take place in one location.
Customer
CustomerID
FirstName
LastName
Car
CarID
Make
Model
Year
CustomerCar
CustomerCarID
CarID
CustomerID
DatePurchaed
This way you can have multiple owners per car, multiple cars per owner and only one record needs to be updated per car and or customer...4th Normal Form.
If I am reading this correctly, you want to take each row from table 1, and create a new record into table A using some of that row data, and then data from the same original row into Table B, Table C but referencing back to Table A again?
If that's the case, you will create TableA with an Identity and make thats the PK.
Insert the required column data into that table and use the #IDENTITY to retrieve the last identity value, then you will insert the remaining data from the original table into the other tables, TableB, TableC, etc. and use the identity you retrieved from TableA as the FK in the other tables.
By Example:
Table 1 has columns col1, col2, col3, col4, col5
Table A has TabAID, col1, col2
Table B has TabBID, TabAID, col3
TableC has TabCID, TabAID, col4
When the first row is read, the values for col1 & col2 are inserted into TableA.
The Identity is captured from that row inserted, and then value for col3 AND the identity are entered into TableB, and then value for col4 AND the identity are entered into TableC.
This is a standard data migration technique for normalizing data.
Hope this assists,

INSERT into table including foreign keys to related tables

Please if someone could help,
I have three tables: 1. Clients; 2 Accounts; 3. Transactions ...
I want to get ClientID by ClientName and also AccountID by AccountName and then insert those ID`s to Transactions and some other values for some other fields that are known ...
Clients
ClientID | ClientName | ...
Accounts
AccountID | AccountName | ...
Transactions
TransID | Account ID | ClientID | Value | Tax | Total
how can i do it ... i tried many many forms of the insert statement but it didnt work
I tried this:
INSERT INTO Transactions (AccountID, ClientID, Value) Values
(SELECT AccountID WHERE AccountName = 'Some Name'
FROM Accounts, SELECT ClientID WHERE ClientName = 'Some Name' FROM Clients, 30.00 )
Value is a reserved word in MS Access.
I think you want something like this:
INSERT INTO Transactions ( AccountID, ClientID, [Value] )
SELECT Accounts.AccountID, Clients.ClientID, 30.00 AS Expr1
FROM Accounts, Clients
WHERE (((Clients.ClientName)='Jimmy') AND ((Accounts.AccountName)='Mark'));
You'll need to rewrite the SQL to properly fit your tables/table names possibly but this worked for me.
You should also make sure Value is a Double data type, not a long integer. (which is the default for a Number field)

update table with values from 2 other tables

I would like to find the nearest Employee for my Customer and update in order table. I tried a Query which throws an error. Can any one suggest what am doing wrong on my query? The only select Statement is working fine. But the update looks some thing wrong.
I have 3 tables
Customer_Master
Customer_ID Customer_Name WHID Cust_Location
Cust100001 Subash WH10001 0xE6100000010C1B2E724F57172A408449F1F109685340
Cust100002 Naresh WH10002 0xE6100000010CBE30992A18152A4093AAED26F8675340
Employee_Master
Emp_ID Emp_name WHID Emp_Location
Emp100001 Prakash WH10001 0xE6100000010C363B527DE7172A4069C36169E0675340
Emp100002 Suresh WH10002 0xE6100000010C98C3EE3B86172A4064E597C118685340
Emp100003 Vincent WH10001 0xE6100000010CE5B8533A58172A4090DD054A0A685340
Emp100004 Paul WH10002 0xE6100000010C2EE6E786A6142A40A0A696ADF5675340
Order_Tran
Order_ID Cust_ID Emp_ID
ORD19847 Cust100001 ?????
ORD19856 Cust100002 ?????
I have Location of the customer and also Employee in Master Tables. Now i want to update Emp_ID in Order_Tran table who is nearest to the customer location in Order Table for Customer Cust100001.
I tried the below query which is showing error
Update Order_Tran Set Emp_ID=(Select Top (1) Emp_ID, Employee_Master.Emp_Location.STDistance(Customer_Master.Cust_Location) AS DistanceApart FROM Customer_Master, Employee_Master WHERE Customer_ID = 'Cust100001'
and Customer_Master.WHID = Employee_Master.WHID ORDER BY DistanceApart);
Try selecting a single value in your sub-query (to stop the error) and adding an outer where clause (to ensure only the specified employee is updated).
UPDATE Order_Tran
SET Emp_ID=(SELECT TOP (1) Emp_ID
FROM Customer_Master, Employee_Master
WHERE Customer_ID = 'Cust100001'
AND Customer_Master.WHID = Employee_Master.WHID
ORDER BY Employee_Master.Emp_Location.STDistance(Customer_Master.Cust_Location))
WHERE Customer_ID = 'Cust100001'

T-SQL for Updating Rows with same value in a column

I have a table lets say called FavoriteFruits that has NAME, FRUIT, and GUID for columns. The table is already populated with names and fruits. So lets say:
NAME FRUIT GUID
John Apple NULL
John Orange NULL
John Grapes NULL
Peter Canteloupe NULL
Peter Grapefruit NULL
Ok, now I want to update the GUID column with a new GUID (using NEWID()), but I want to have the same GUID per distinct name. So I want all the John Smiths to have the same GUID, and I want both the Peters to have the same GUID, but that GUID different than the one used for the Johns. So now it would look something like this:
NAME FRUIT GUID
John Apple f6172268-78b7-4c2b-8cd7-7a5ca20f6a01
John Orange f6172268-78b7-4c2b-8cd7-7a5ca20f6a01
John Grapes f6172268-78b7-4c2b-8cd7-7a5ca20f6a01
Peter Canteloupe e3b1851c-1927-491a-803e-6b3bce9bf223
Peter Grapefruit e3b1851c-1927-491a-803e-6b3bce9bf223
Can I do that in an update statement without having to use a cursor? If so can you please give an example?
Thanks guys...
Update a CTE won't work because it'll evaluate per row. A table variable would work:
You should be able to use a table variable as a source from which to update the data. This is untested, but it'll look something like:
DECLARE #n TABLE (Name varchar(10), Guid uniqueidentifier);
INSERT #n
SELECT Name, newid() AS Guid
FROM FavoriteFruits
GROUP BY Name;
UPDATE f
SET f.Guid = n.Guid
FROM #n n
JOIN FavoriteFruits f ON f.Name = n.Name
So that populates a variable with a GUID per name, then joins it back to the original table and updates accordingly.
To clarify comments re a table expression in the USING clause of a MERGE statement.
The following won't work because it'll evaluate per row:
MERGE INTO FavoriteFruits
USING (
SELECT NAME, NEWID() AS GUID
FROM FavoriteFruits
GROUP
BY NAME
) AS source
ON source.NAME = FavoriteFruits.NAME
WHEN MATCHED THEN
UPDATE
SET GUID = source.GUID;
But the following, using a table variable, will work:
DECLARE #n TABLE
(
NAME VARCHAR(10) NOT NULL UNIQUE,
GUID UNIQUEIDENTIFIER NOT NULL UNIQUE
);
INSERT INTO #n (NAME, GUID)
SELECT NAME, NEWID()
FROM FavoriteFruits
GROUP
BY NAME;
MERGE INTO FavoriteFruits
USING #n AS source
ON source.NAME = FavoriteFruits.NAME
WHEN MATCHED THEN
UPDATE
SET GUID = source.GUID;
There's a single-statement solution too, which, however, has some limitations. The idea is to use OPENQUERY(), like this:
UPDATE FavoriteFruits
SET GUID = n.GUID
FROM (
SELECT NAME, GUID
FROM OPENQUERY(
linkedserver,
'SELECT NAME, NEWID() AS GUID FROM database.schema.FavoriteFruits GROUP BY NAME'
)
) n
WHERE FavoriteFruits.NAME = n.NAME
This solution implies that you need to create a self-pointing linked server. Another specificity is that you can't use this method on table variables nor local temporary tables (global ones would do as well as 'normal' tables).

Resources