Update with join and temp table - sql

I have table that called hanpaka there I want to update the cardNum from temp table the connection between the two is IDMember and MemberId. but updating like this cause multiple cardNum not to the right MemberId why?
UPDATE Knowledge4All..Hanpaka
SET CardNum = (c.CardNumber )
FROM #Temp2 c inner join Hanpaka h on IDMember = h.MemberId`

Try using the alias in the update:
UPDATE h
SET CardNum = c.CardNumber
FROM #Temp2 c JOIN
Hanpaka h
ON c.IDMember = h.MemberId;
SQL Server does allow the table to be repeated in the update. However, it might get confused and your query might be doing a Cartesian product.

Related

Update different data type columns

I have two tables GCB.NewsOne & GCB.NewsTwo both table are same except one column
it's GCode in dbo.News table GCode is varchar(100) null and GCB.News table has a bigint null column.
Now I want to update the code in GCode in dbo.News to the value of GCB.News.
I tried like below, but it's not working
UPDATE [GCB].[NewsOne] AS G
SET G.Code = (SELECT P.Code FROM GCB.NewsTwo P WHERE G.ID = P.ID)
Try casting the bigint to varchar:
UPDATE G
SET Code = CAST(P.Code AS VARCHAR(MAX))
FROM [GCB].[NewsOne] G
INNER JOIN GCB.NewsTwo P
ON G.ID = P.ID;
This assumes that your problem really is the types of the two codes, and not something else.
Also note that I rewrote your join using update join syntax, which I think is easier to read.
You may not use an alias in an update statement. This works fine:
UPDATE [GCB].[NewsOne]
SET [GCB].[NewsOne].Code = ( SELECT P.Code FROM GCB.NewsTwo P
WHERE [GCB].[NewsOne].ID=P.ID )

SQL updating master table with updates from update table

I am trying to update my master table from my updates table, What it wrong with the below query.
UPDATE master_table
SET master_table.description = master_table_import.description
FROM master_table_import
WHERE master_table.user_id = master_table_import.user_id
You are missing a join between the tables. Try something like this:
UPDATE mt SET mt.Description = mti.Description
FROM master_table mt
INNER JOIN master_table_import mti
ON mt.user_id = mti.user_id;
It is always good idea to use aliases for tables. To update you have join your target table with source table:
UPDATE mt
SET description = mti.description
FROM master_table mt INNER JOIN master_table_import mti
WHERE mt.user_id = mti.user_id

Update SQL with Aliased tables still returns "table is ambiguous" error

I am trying to run the below update but running into the "table is ambiguous" error.
UPDATE dbo.cg
SET cg.column = gId.ID
FROM dbo.a
INNER JOIN dbo.cg as cId ON cId.[a] = dbo.a.[c]
INNER JOIN dbo.cg as gId ON gId.[a] = dbo.a.[b];
The table dbo.a contains data to update a value in cg based on a relationship to same table against a value in a different column. It is a self-referencing hierarchy.
As you can see, everything is aliased so I am a bit confused why this won't run.
Many thanks in advance for any help that can be provided.
In SQL Server, you should use the alias in the update, not the table. In addition, you have no alias called cg. So something like this:
UPDATE cId
SET column = gId.ID
FROM dbo.a a INNER JOIN
dbo.cg cId
ON cId.[a] = a.[c] INNER JOIN
dbo.cg gId
ON gId.[a] = a.[b];
Not to worry, solved it by luck.
I inner joined the table to itself in desperation ...
UPDATE dbo.cg
SET cg.column = gId.ID
FROM dbo.a
INNER JOIN dbo.cg as cId ON cId.[a] = dbo.a.[c]
INNER JOIN dbo.cg as gId ON gId.[a] = dbo.a.[b]
INNER JOIN cg ON cId.[a] = cg.[a];
If anyone could explain why that has worked, I would really appreciate understanding the MS SQL logic underneath.

SQL Creating a temp table for this Query

I want to create a temp table to store this query so that I can then update another table.
SELECT SaginawUtilityData.ServiceFrom, SaginawUtilityData.ServiceThru,
BillingMonth = dbo.fn_MonthWithMostDaysInRange(ServiceFrom, ServiceThru),
SaginawUtilityData.Usage, SaginawUtilityData.UtilityCharges
FROM SaginawUtilityData
JOIN tblMEP_CustomerAccounts
ON SaginawUtilityData.AccountNumber = tblMEP_CustomerAccounts.AccountNumber
JOIN tblMEP_Customers
ON tblMEP_CustomerAccounts.CustomerID = tblMEP_Customers.ID
JOIN tblMEP_UtilityCompanies
ON tblMEP_UtilityCompanies.ID = tblMEP_CustomerAccounts.UtilityCompanyID
JOIN tblMEP_Meters
ON tblMEP_CustomerAccounts.ID = tblMEP_Meters.CustomerAccountID
WHERE tblMEP_Customers.ID = 43
It would be great if you can just do the update: this is the other table and the columns I want to insert from the table above into this one:
SELECT tblMEP_MonthlyDATA.CycleStartDate, tblMEP_MonthlyDATA.CycleEndDate,
tblMEP_MonthlyDATA.BillingMonth, tblMEP_MonthlyDATA.Consumption,
tblMEP_MonthlyDATA.Charge
FROM tblMEP_MonthlyData
Thanks.
I'm uncertain whether I really understand what you're asking but I think you're asking how you can put the data from the top query straight into the table columns shown in the bottom query, so:
INSERT tblMEP_MonthlyDATA (
CycleStartDate, CycleEndDate, BillingMonth, Consumption, Charge)
SELECT
SaginawUtilityData.ServiceFrom,
SaginawUtilityData.ServiceThru,
dbo.fn_MonthWithMostDaysInRange(ServiceFrom, ServiceThru),
SaginawUtilityData.Usage,
SaginawUtilityData.UtilityCharges
FROM SaginawUtilityData
JOIN tblMEP_CustomerAccounts ON SaginawUtilityData.AccountNumber =
tblMEP_CustomerAccounts.AccountNumber
JOIN tblMEP_Customers ON tblMEP_CustomerAccounts.CustomerID = tblMEP_Customers.ID
JOIN tblMEP_UtilityCompanies ON tblMEP_UtilityCompanies.ID =
tblMEP_CustomerAccounts.UtilityCompanyID
JOIN tblMEP_Meters ON tblMEP_CustomerAccounts.ID = tblMEP_Meters.CustomerAccountID
WHERE
tblMEP_Customers.ID = 43 --or other set of conditions
Hope this helps (or is at least vaguely relevant to what you want to know)

SQL Server 2008: Select then update statement

I'm doing a INNER JOIN across 6 tables for a module for my application, basically it takes the prostaff an gets their name and email, and compares that to a list of job applicants.
On the mod_employmentAppJobs I need to set a column for each row selected to true. Basically this sets a flag that tells the sql not to select the column because we already sent an email on that user. It's a bit field.
How do I set the emailSent field to true on a SQL statement? -- Coldfusion 8 is the Application server, just FYI....
SELECT *
FROM pro_Profile p
INNER JOIN pro_Email e ON p.profileID = e.profileID
INNER JOIN mod_userStatus m ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a ON p.profileID = a.departmentID
<!--- Join Job titles to the jobs --->
INNER JOIN mod_employmentAppJobs b ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
You have a couple of choices.
1) Use a temp table and select data there first, update the mod_employmentAppJobs, and perform a select from the temp table to get your data retrieved.
So, it would look something like this.
create a temp table
CREATE TABLE #tmpTABLE
(
EmailAddress varchar(100),
JobTitle varchar(50),
JobTitleId bigint
......
)
Insert into it
INSERT INTO #tmpTable
SELECT EmailAddress,JobTitle, ........
FROM pro_Profile p
INNER JOIN pro_Email e
ON p.profileID = e.profileID
INNER JOIN mod_userStatus m
ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a
ON p.profileID = a.departmentID
INNER JOIN mod_employmentAppJobs b
<!--- Join Job titles to the jobs --->
ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c
ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
Update the source table (I'd recommend an index on jobTitleId in the temp table for performance if applicable)
UPDATE mod_employmentAddJobs
SET EmailSent="true"
FROM mod_employmentAppJobs b
INNER JOIN #tmpTable tmp
ON b.jobTitleID=tmp.jobTitleID
Get the actual data back to the app layer
SELECT * FROM #tmpTable
For better taste, I recommend sprinkling with BEGIN TRAN...COMMIT...ROLLBACK and BEGIN TRY..END TRY BEGIN CATCH...END CATCH to taste and to business requirements.
Also, it's good manners to drop the temp table after you are done with it, even though SQL server will not take offense if you don't.
2) You can use the OUTPUT clause of the update statement.
UPDATE mod_employmentAddJobs
SET EmailSent="true"
FROM pro_Profile p
INNER JOIN pro_Email e
ON p.profileID = e.profileID
INNER JOIN mod_userStatus m
ON p.profileID = m.profileID
<!--- Joins the pro staff profiles to the employment app --->
INNER JOIN mod_employmentAppJobTitles a
ON p.profileID = a.departmentID
INNER JOIN mod_employmentAppJobs b
<!--- Join Job titles to the jobs --->
ON a.jobTitleID=b.jobTitleID
<!--- Joining the table on where the profile equals everything else --->
INNER JOIN mod_employmentAppProfile c
ON c.eAppID = b.eAppID
WHERE b.emailSent = 'False'
OUTPUT inserted.*
This should get you the resultset right back to your app layer
You could store the result in a temporary table. You can use the data in the temporary table, and still return it at the end. It's a lot of typing but pretty straightforward:
-- Select data into temporary table
declare #result table (jobTitleID int, ...)
INSERT #result
(jobTitleID, ...)
SELECT jobTitleID
FROM pro_Profile p
...
-- Update unreadMail flag
update mod_employmentAppJobs
set unreadMail = 'False'
where jobTitleID in (select jobTitleId from #result)
-- Return result to application
select jobTitleId, ...
from #result
If you need to update and then return the data then probably the best is to use a Stored Procedure, where you first query the data, update it and then return it.
Well, this is just an idea, not the best solution.
You could get data (for which bit is false) in a DataReader and then execute a Command setting bit to true for ids contained in Dataset.
Dataset returns data you need...
I just tacked a on the end and it worked:
UPDATE mod_employmentAppJobs
SET emailSent = 'True'