Multi part identifier could not be found using a temp table - sql

I have the following query which populates a temporary table:
with CTE as
(
select a.accountid as 'myid',
a.new_mprnnumber,
a.new_customernumber,
b.*,
row_number()
over (partition by new_customernumber -- add additional partitions as you would group bys
order by billingPeriodEndDate desc) as r_ord
from [CRM].[crm4_MSCRM].[dbo].[AccountExtensionBase] a
inner join bill b
on a.new_mprnnumber = b.MPRN
where new_accountstage = 7
and new_accounttype = 2
)
select *
into #tempCTE
from CTE
where r_ord = 1
After gathering the information in the temporary table I want to iterate through each record and update the main table using the accountid but using the following statement:
update [CRM].[crm4_MSCRM].[dbo].[AccountExtensionBase]
set new_invoicenumber = invoicenumber
where accountid = #tempCTE.myid
I am getting the error that the multi part identifier could not be bound, any idea on what is causing this issue?

You need to bring in the temporary table:
update aeb
set new_invoicenumber = t.invoicenumber
from [CRM].[crm4_MSCRM].[dbo].[AccountExtensionBase] aeb join
#tempCTE t
on aeb.accountid = t.myid;
As a note, you don't need a temporary table. You can just do:
with tempCTE as ( . . . )
update aeb
set new_invoicenumber = t.invoicenumber
from [CRM].[crm4_MSCRM].[dbo].[AccountExtensionBase] aeb join
tempCTE t
on aeb.accountid = t.myid
where tempCTE.r_ord = 1

Related

Update only first record from duplicate entries in SQL Server

I need help trying to update a table that has multiple duplicate records, but I am stuck.
I have this table, and I need to update im_cust9 with the alt_item_id1 value.
The query I am using to get this result from the table is the following:
SELECT
o.item_id, o.alt_item_id1, o.im_cust9, o.owner_id, o.if_updatestamp
FROM
item_master o
INNER JOIN
(SELECT
alt_item_id1, COUNT(*) AS dupeCount
FROM
item_master
WHERE
owner_id = 'GIII' AND alt_item_id1 <> ''
GROUP BY
alt_item_id1
HAVING
COUNT(*) > 1) oc ON o.alt_item_id1 = oc.alt_item_id1
WHERE
owner_id = 'GIII' AND o.alt_item_id1 <> ''
ORDER BY
alt_item_id1, if_updatestamp ASC
Not sure how to update the oldest record of every set of duplicate alt_item_id1
I am using SQL Server 2012
Any help is greatly appreciated!
To get the newest row to update, use the max of the if_updatestamp. for the oldest use the min. Then join it to your table for the udpate like so...
update IM
Set IM.im_cust9 = NewDupeRow.alt_item_id1
From item_master IM
JOIN (
SELECT alt_item_id1,Max(if_updatestamp) MaxUpdateValue
FROM item_master WHERE owner_id='GIII' AND alt_item_id1<>''
GROUP BY alt_item_id1 ) NewDupeRow
On IM.alt_item_ID = NewDupeRow.alt_item_ID
AND IM.if_updatedstamp = NewDupeRow.MaxUpdateValue
You can do this using an updatable CTE and row_number():
with toupdate as (
select i.*,
row_number() over (partition by alt_item_id order by if_updatestamp) as seqnum
from item_master i
)
update toupdate
set im_cust9 = alt_item_id1
where seqnum = 1;

How to speed up update query in SQL Server 2008?

update orders
set tname = (select top 1 t.task
from task t
where prod_typ='2' and sorder_nbr = t.ORDER_NBR
order by t.strt_dt desc)
where Prod_type='2'
update orders
set tname= (select top 1 t.task
from task t
where prod_typ='1' and sorder_nbr=t.ORDER_NBR
order by t.strt_dt desc)
where Prod_type='1'
I am trying to update the tname column of orders table by the latest task from the task table
And the condition is prod_typ of orders table is 1 and sorder_nbr of orders table and order_nbr of task table are equal
My first update statement works well where the rows are 900k and for the second update rows are 400k for second update statement it takes more than one hour to run and at last I cancelled the query
1) You query and my query:
update orders
set tname = (select top 1 t.task
from task t
where prod_type='2' and order_nbr = t.ORDER_NBR
order by t.strt_dt desc)
where Prod_type='2';
go
update o
set tname = (select top 1 t.task
from task t
where prod_type='2' and o.order_nbr = t.ORDER_NBR
order by t.strt_dt desc)
from dbo.orders o
where Prod_type='2';
go
The actual execution plans:
As you can see, if default collation for current DB is CI (case insensitive) then following predicate order_nbr=t.ORDER_NBR force SQL Server to compare the values of t.ORDER_NBR with the values order_nbr column from the same table task t. Look at first execution plan which corresponds to first query.
To solve just this problem, I've used another alias
dbo.orders o and I've reqrite the predicate thus o.order_nbr = t.ORDER_NBR. You may see this also within second execution plan.
Depending on how many tasks are for every order_num & prod_type you could test S#1 if there are many tasks or S#2 if there is a small amount of tasks per order_num & prod_type. Again, you need to test with your data to see which solution is better.
2) Solution #1:
UPDATE o
SET tname =
COALESCE(
(SELECT TOP(1) t.task
FROM dbo.task t
WHERE t.prod_type=o.Prod_type
AND o.order_nbr = t.ORDER_NBR
ORDER BY t.strt_dt DESC), tname
)
FROM dbo.orders o
WHERE o.Prod_type IN ('1', '2');
3) Solution #2:
UPDATE o
SET tname = lt.task
FROM dbo.orders o
INNER JOIN
(
SELECT src.order_nbr, src.prod_type, src.task
FROM (
SELECT t.ORDER_NBR, t.prod_type, t.task,
ROW_NUMBER() OVER(PARTITION BY t.ORDER_NBR, t.prod_type ORDER BY t.strt_dt DESC) RowNum
FROM dbo.task t
) src
WHERE src.RowNum = 1
) lt -- last task
ON o.order_nbr = lt.ORDER_NBR AND o.prod_type = lt.prod_type
WHERE o.Prod_type IN ('1', '2');
If you have questions then feel free to ask.
4) An index on dbo.task(order_nbr, prod_type, strt_dt) include (task) should help both solutions.
5) Also you should publish the actual execution plans.
If the data size is large than i suggest you to use variables for updating the table, or Using CTE to update
Update a table using CTE and NEWID()
Updating record using CTE?
I hope this will help
with tname (t.task) as
(select top 1 t.task
from task t
where prod_typ='2' and order_nbr = t.ORDER_NBR
order by t.strt_dt desc )
insert into Orders(t.task)
Try something like this. This will update prod_type of 1 and 2 at the same time.
UPDATE orders
SET tname = t1.task
FROM orders o
CROSS APPLY (
SELECT order_nbr, prod_type, t.task, row_number() OVER (PARTITION BY order_nbr, prod_type ORDER BY strt_dt DESC) rownumber
FROM task t
WHERE o.prod_type = t.prod_type
AND o.order_nbr = t.order_nbr) t1
WHERE t1.rownumber = 1
AND o.prod_type in (1,2)
Using a CTE query will speed up this, because the subquery is need not be created for every row, it is pre-prepared. Here is the sqlfiddle
;with cteTaskNames as
(
select top 1 t.task
from task t
where prod_type='2' and order_nbr=t.ORDER_NBR
order by t.strt_dt desc
)
update orders
set tname = (select task from cteTaskNames)
where Prod_type='2'
go
Also,
1) Is "prod_type" an integer field or a string field?
2) If you add group by in the cte, you can do an inner join on orders and cte query to run all updates at once instead of doing each query.

SQL Update Skipping duplicates

Table 1 looks like the following.
ID SIZE TYPE SERIAL
1 4 W-meter1 123456
2 5 W-meter2 123456
3 4 W-meter 585858
4 4 W-Meter 398574
As you can see. Items 1 and 2 both have the same Serial Number. I have an innerjoin update statement that will update the UniqueID on these devices based on linking their serial number to the list.
What I would like to do. Is modify by hand the items with duplicate serial numbers and scripted update the ones that are unique. Im presuming I have to reference the distinct command here somewhere buy not sure.
This is my update statement as is. Pretty simple and straight forward.
update UM00400
Set um00400.umEquipmentID = tb2.MIUNo
from UM00400 tb1
inner join AA_Meters tb2 on
tb1.umSerialNumber = tb2.Old_Serial_Num
where tb1.umSerialNumber <> tb2.New_Serial_Num
;WITH CTE
AS
(
SELECT * , rn = ROW_NUMBER() OVER (PARTITION BY SERIAL ORDER BY SERIAL)
FROM UM00400
)
UPDATE CTE
SET CTE.umEquipmentID = tb2.MIUNo
inner join AA_Meters tb2
on CTE.umSerialNumber = tb2.Old_Serial_Num
where tb1.umSerialNumber <> tb2.New_Serial_Num
AND CTE.rn = 1
This will update the 1st record of multiple records with the same SERIAL.
If i understand your question correctly below query will help you out :
;WITH CTE AS
(
// getting those serial numbers which are not duplicated
SELECT umSerialNumber,COUNT(umSerialNumber) as CountOfSerialNumber
FROM UM00400
GROUP BY umSerialNumber
HAVING COUNT(umSerialNumber) = 1
)
UPDATE A SET A.umEquipmentID = C.MIUNo
FROM UM00400 A
INNER JOIN CTE B ON A.umSerialNumber = B.umSerialNumber
INNER JOIN AA_Meters C ON A.umSerialNumber = C.Old_Serial_Num

How to increment a column based on two tables that are joined

I am trying to increment a column on a sql server table based on the join between the initial table and the joined table. The idea is to update tblForm10Objectives, set the ObjectiveNumber column to an increment number starting with 1 based on the number of rows returned from the join of tblForm10GoalsObjectives and tblForm10Objectives where ID_Form10Goal equals a number. Example query so far:
Update tblForm10Objectives
Set ObjectiveNumber = rn
From (
Select ROW_NUMBER() over (PARTITION by OG.ID_Form10Goal) as rn
, *
From (
Select *
From tblForm10GoalsObjectives OG
Join tblForm10Objectives O On OG.ID_Form10Objective = O.ID_Form10Objective
Where OG.ID_Form10Goal = 4
Order by O.ID_Form10Objective
) as tblForm10Objectives;
If the select portion of the query is performed the columns are displayed so you can see the ObjectiveNumber is currently 0 where ID_Form10Goal = 4
Once the update runs I need for the ObjectiveNumber to show 1 , 2; since there are two rows for ID_Form10Goal = 4.
I had to introduce a new table to the logic of this update statement, the table name is tblForm10Goals. The objectives need to be pulled by ID_Agency instead of ID_Form10Goal I am getting an error message stating a "a multipart identifier 'dbo.tblForm10Objectives.ID_Form10Objective = rns.ID_Form10Objective' could not be bound. I am using the following SQL Update statement:
UPDATE dbo.tblForm10Objectives
SET ObjectiveNumber = rn
FROM tblForm10Goals As g
Left Join tblForm10GoalsObjectives gobs ON g.ID_Form10Goal = gobs.ID_Form10Goal
Right Join
(
SELECT
ROW_NUMBER() OVER (PARTITION BY g.ID_Agency
ORDER BY OB.ID_Form10Objective) AS rn,
OB.ID_Form10Objective
FROM tblForm10Goals g
LEFT JOIN dbo.tblForm10GoalsObjectives gobs ON g.ID_Form10Goal = gobs.ID_Form10Goal
RIGHT JOIN dbo.tblForm10Objectives OB ON gobs.ID_Form10Objective = OB.ID_Form10Objective
Where g.ID_Agency = 2
) rns ON dbo.tblForm10Objectives.ID_Form10Object = rns.ID_Form10Objective
Your example seems to be missing a closing parenthesis somewhere, and without the table structures to look at, I can't be certain of my answer. It seems you have two tables:
tblForm10Objectives
-------------------
ID_Form10Objective
ObjectiveNumber
...
and
tblForm10GoalsObjectives
------------------------
ID_Form10Goal
ID_Form10Objective
...
If this is the case, the following query should give you the results you desire:
UPDATE dbo.tblForm10Objectives
SET ObjectiveNumber = rn
FROM dbo.tblForm10Objectives INNER JOIN
(
SELECT
ROW_NUMBER() OVER (PARTITION BY OG.ID_Form10Goal
ORDER BY O.ID_Form10Objective) AS rn,
O.ID_Form10Objective
FROM dbo.tblForm10Objectives O INNER JOIN
dbo.tblForm10GoalsObjectives OG ON OG.ID_Form10Objective = O.ID_Form10Objective
Where OG.ID_Form10Goal = 4
) rns ON dbo.tblForm10Objectives.ID_Form10Objective = rns.ID_Form10Objective
If you run the inner SELECT statement, you will see the desired ObjectiveNumber values and the corresponding ID_Form10Objective that will get updated with those values.
If you post your table structures, I or someone else may be able to be of more help.

Update in child table, only one value got updated

Below I am trying to update value of a parent table from child table and counting matching values. Tables in my db:
issue_dimension with id = issue_id and have column accno.
star_schema with id star_id,this Child column have fk issue_id and column book_frequency
The book_frequency need to match the count of each accno in parent table , I tried this
update [test1] .[dbo] .star_schema
set [book_frequency] = (
select top 1 COUNT([issue_dimension].ACCNO)as book_frequency
from issue_dimension
group by ACCNO having (COUNT(*)>1) and
issue_dimension.ACCNO = star_schema .ACCNO
)
It only updates only 1st value count issue_dimension. I need to count every accno in issue_dimension and update it to matching accno of star_schema.
I never did update by joining two or more tables , can anyone help in this with joins
UPDATE s
SET [book_frequency] = i.CNT
FROM [test1].[dbo].star_schema s
INNER JOIN
(
SELECT ACCNO, COUNT(*) as CNT
FROM issue_dimension
GROUP BY ACC_NO
HAVING COUNT(*)>1
) i on (s.ACCNO = i.ACCNO)
I didn't check it but it should works
Try in this way, without grouping, just with the WHERE clause:
UPDATE [test1].[dbo].star_schema SET
[book_frequency] =
(
SELECT COUNT([issue_dimension].ACCNO)
FROM issue_dimension
WHERE issue_dimension .ACCNO = star_schema.ACCNO
HAVING COUNT(*)>1
)
It's not fully clear to me so the answer is a bit of guessing:
update s set
book_frequency = t.qty
from star_schema s
join issue_dimension i on s.issue_id = s.issue_id
join (select count(*) as qty, accno
from issue_dimension
group by accno
) t on i.accno = t.accno
Here's the example from BOL that does the kind of thing you're looking for, using AW:
USE AdventureWorks2008R2;
GO
UPDATE Sales.SalesPerson
SET SalesYTD = SalesYTD +
(SELECT SUM(so.SubTotal)
FROM Sales.SalesOrderHeader AS so
WHERE so.OrderDate = (SELECT MAX(OrderDate)
FROM Sales.SalesOrderHeader AS so2
WHERE so2.SalesPersonID = so.SalesPersonID)
AND Sales.SalesPerson.BusinessEntityID = so.SalesPersonID
GROUP BY so.SalesPersonID);