Update query where set statement gets value from another table - sql

SQL Server 2008 R2
Table CIRTB
CIRLogID PrimaryKey
StaffName
StaffID
Table StaffTB
StaffID - PrimaryKey
Fullname
DOB
CIN
Program
I have StaffID's in the CIRTB table that are Null, so I need to update it from the Staff table.
I know I need something like the following
update CIRTB
set CIRTB>staffid = (select staffid
from stafftb
where stafftb.fullname = cirtb.Staffname)
where CIRTB.staffid is null
One problem that I am stuck on: there are some duplicates in the StaffTB for fullname, dob, program

One way to do the UPDATE is using a CTE:
;WITH ToUpdate AS (
SELECT t1.StaffID AS t1_StaffID, t2.StaffID AS t2_StaffID,
ROW_NUMBER() OVER (PARTITION BY t2.Fullname
ORDER BY t2.DOB DESC) AS rn
FROM CIRTB AS t1
JOIN StaffTB AS t2 ON t1.StaffName = t2.Fullname
WHERE t1.StaffID IS NULL
)
UPDATE ToUpdate
SET t1_StaffID = t2_StaffID
WHERE rn = 1
The CTE uses ROW_NUMBER in order to pick one record per Fullname. The ORDER BY clause of the window function determines which record is picked in case of duplicates: since DOB DESC is used, the record having the most recent DOB is selected.

Use TOP 1 in the sub-select to make sure it only returns one row even if there are duplicates.

Related

Sql Server query problem in Update Statement

I have Table Job in which i have a column name MainJob_Id name
So i just want to Update Container_TypeId Column Value as 1,2,3...go on...
when MainJob_id is same...
else MainJob_id is new then start again as 1
Execpted Result
Try using an updatable CTE:
WITH cte AS (
SELECT ContainerTypeId,
ROW_NUMBER() OVER (PARTITION BY MainJob_Id ORDER BY LengthId DESC) rn
FROM yourTable
)
UPDATE cte
SET ContainerTypeId = rn;
However, you might want to not do this update and instead just select the sequence you want at the time you query.

Data based on first row value in sql server

I have a table Activity having data like below.It contains multiple rows of CreatedBY like IVR,Raghu and IT.
But I need to get the data only when the first row of CreatedBY='IVR'.
This following query will return firstcreated row for each user (CreatedBy)-
SELECT * FROM
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY CreatedBy ORDER BY CreatedBy,[Date And Time]) RN
FROM your_table
)A
WHERE RN = 1
I suspect you want the first row per ticket_no. At least, that makes more sense as a query.
If so, in SQL Server, you can use a correlated subquery:
select a.*
from activity a
where a.createdby = 'Raghu' and
a.datetime = (select min(a2.datetime)
from activity a2
where a2.ticket_no = a.ticket_no
);
use exists
select a.*
from table a where createdby='IVR'
and datetime in
(select min(datetime) from table b where a.ticketno=b.ticketno
and createdby='IVR')

Update one specific row where same employee id has multiple entries in sql

I am new to sql and stuck in duplicate entries update issue, any help would be greatly appreciated.
I have a table call employee history, it has empid, roleid, rolestartdate, roleenddate columns.
In the table there are multiple entries for one empid based on role assignment and unassignment.
I need to update only one empid row based on below condition.
Select one empid row where rolestartdate is Max date, if it returns more than one row, check roleid columns and filter based on Max roleid.
It should also return those empid rows which has only one entry.
Thank you
You can use Row_Number window function.
;with cte as
(
select *,
Rn = row_number()over(partition by empid order by rolestartdate desc, roleid desc)
from EmployeeHistory
)
/*
--To check the records which will be updated
Select * from cte where Rn = 1
*/
update cte
set update_column = 'whatever value'
where Rn = 1

LIMIT equivalent for SQL Server 2012 in an UPDATE statement

I have the following table below and am trying to update the first available row with an user ID through a query, but I need to limit this to only update one row and not multiple.
ID Model UserID
1 X12T5 1
2 X13T5 2
3 X14T5 NULL
4 X15T5 NULL
The first available row would be where ID is 3. I would update it with the following query:
UPDATE Table SET UserID = '3' WHERE UserID IS NULL
But I want to make sure it affects only 1 row and not multiple that are available, LIMIT doesn't exist in SQL Server.
What would the best way to achieve this?
You can do this with UPDATE TOP. It's the equivalent of a SELECT TOP but for updates; and TOP is SQL Server's equivalent of MySQL's LIMIT.
See further info.
UPDATE Table SET UserID = '3'
WHERE UserID IS NULL
AND Id IN (SELECT top 1 ID FROM table where UserId IS NULL)
You can also use any of the following methods (Assuming column ID is of integer datatype)
Using subquery :
UPDATE a
SET a.UserID='3'
FROM YourTable a
WHERE ID =( SELECT MIN(ID)
FROM YourTable
WHERE UserID is NULL)
Using JOIN:
UPDATE a
SET a.UserID='3'
FROM YourTable a
JOIN
( SELECT MIN(ID) MinId
FROM YourTable
WHERE UserID is NULL) b
ON a.ID=b.MinId
Using CTE
WITH cte_a
AS
(SELECT MIN(ID) MinId
FROM YourTable
WHERE UserID is NULL)
UPDATE a
SET a.UserID='3'
FROM YourTable a
JOIN cte_a b a.ID=b.MinId
You can also use CTE & perform the SELECT\UPDATE\DELETE operations ,
; WITH CTE AS (
SELECT TOP 10 * FROM TABLE
)
UPDATE CTE
SET ...
DELETE\UPDATE\SELECT works with CTE ... Cool !!!

Select a NON-DISTINCT column in a query that return distincts rows

The following query returns the results that I need but I have to add the ID of the row to then update it. If I add the ID directly in the select statement it will return me more results then I need because each ID is unique so the DISTINCT statement see the line as unique.
SELECT DISTINCT ucpse.MemberID, ucpse.ProductID, ucpse.UserID
FROM UserCustomerProductSalaryExceptions as ucpse
WHERE EXISTS (SELECT NULL
FROM UserCustomerProductSalaryExceptions as upcse2
WHERE ucpse.userid = upcse2.userid AND ucpse.MemberID = upcse2.MemberID AND ucpse.ProductID = upcse2.ProductID
GROUP BY upcse2.UserID, upcse2.memberid, upcse2.productid
HAVING COUNT(UserID) >= 2
)
So basically I need to add ucpse.ID in the Select statement while keeping DISTINCT values for MemberID,ProductID and UserID.
Any Ideas ?
Thank you
According to you comment:
If the data has been duplicated 67 times for a given employee with a given product and a given client, I need to keep only one of thoses records. It's not important which one, so this is why I use DISTINC to obtain unique combinaison of given employee with a given product and a given client.
You can use MIN() or MAX() and GROUP BY instead of DISTINCT
SELECT MAX(ucpse.ID) AS ID, ucpse.MemberID, ucpse.ProductID, ucpse.UserID
FROM UserCustomerProductSalaryExceptions as ucpse
WHERE EXISTS (SELECT NULL
FROM UserCustomerProductSalaryExceptions as upcse2
WHERE ucpse.userid = upcse2.userid AND ucpse.MemberID = upcse2.MemberID AND ucpse.ProductID = upcse2.ProductID
GROUP BY upcse2.UserID, upcse2.memberid, upcse2.productid
HAVING COUNT(UserID) >= 2
)
GROUP BY ucpse.MemberID, ucpse.ProductID, ucpse.UserID
UPDATE:
From you comments I think the below query is what you need
DELETE FROM UserCustomerProductSalaryExceptions
WHERE ID NOT IN ( SELECT MAX(ucpse.ID) AS ID
FROM #UserCustomerProductSalaryExceptions
GROUP BY ucpse.MemberID, ucpse.ProductID, ucpse.UserID
HAVING COUNT(ucpse.ID) >= 2
)
If all you want is to delete the duplicates, this will do it:
WITH X AS
(SELECT ID,
ROW_NUMBER() OVER (PARTITION BY MemberID, ProductID, UserID ORDER BY ID) AS DupRowNum<br
FROM UserCustomerProductSalaryExceptions
)
DELETE X WHERE DupRowNum > 1
ID's not necessary - try:
UPDATE uu SET
<your settings here>
FROM UserCustomerProductSalaryExceptions uu
JOIN ( <paste your entire query above here>
) uc ON uc.MemberID=uu.MemberId AND uc.ProductID=uu.ProductId AND uc.UserID=uu.UserId
From the sound of your data structure (which I would STRONGLY advise normalizing as soon as possible), it sounds like you should be updating all the records. It sounds as if each duplicate is important because it contains some information about an employee's relation to a customer or product.
I would probably update all the records. Try this:
UPDATE UCPSE
SET
--Do your updates here
FROM UserCustomerProductSalaryExceptions as ucpse
JOIN
(
SELECT UserID, MemberID, ProductID
FROM UserCustomerProductSalaryExceptions
GROUP BY UserID, MemberID, ProductID
HAVING COUNT(UserID) >= 2
) T
ON ucpse.UserID = T.UserID AND ucpse.MemberID = T.MemberID AND ucpse.ProductID = T.ProductID