Distinct in update query - sql-server

I want to update distinct emp number to users in the table.
In table there are many records for single user, so need to update same emp num for single user and then increment accordingly.
And also those user's are available in multiple table and all should share the same ID.
Ex : Table 1
ID Name
875667 Test1
875667 Test1
875667 Test1
792380 Test2
792380 Test2
Need to update the ID like 111111 and then increment accordingly and also share the same ID in other tables
Ex : Table 2
ID Name
875667 Test1
875667 Test1
This should have same ID as table1 after updating ID - 111111
Please advice!

It looks like you are using SQL Server. If so, you can use updatable CTEs:
with toupdate as (
select t1.*,
dense_rank() over (order by id) as seqnum
from [Database].[dbo].[table1] t1
)
update toupdate
set id = convert(nvarchar(255), 11111110 + seqnum);

Related

SQL Server - Merging one record to another and changing items referencing the first item to reference the item it was merged into

I have a duplicate record in a SQL Server table with (obviously) different unique IDs.
CustomerId FirstName LastName|
1 John Doe |
2 John Doe |
There are child items that are already in the database (let's say an orders table), some relate to one of the items and some relate to the other.
OrderId CustomerId DateEntered|
100 1 2018/11/01 |
101 2 2018/11/09 |
They are both referring to the same customer.
I would like to delete the duplicate record. Is there a way to automatically update the CustomerIds in the Orders table that has a value of 2 to have a value of 1?
You can use a window function to solve this
WITH CTE AS
(
SELECT T1.*,
MIN(T1.CustomerId) OVER(PARTITION BY T1.FirstName, T1.LastName ORDER BY T1.CustomerId) RN
FROM T1
)
UPDATE T2
SET T2.CustomerId = CTE.RN
FROM T2 INNER JOIN CTE ON T2.CustomerId = CTE.CustomerId;
Demo
But in the first place you need to fix this, the customer should have one(1) Unique id, not multiple IDs.

How to insert records from one table to another using trigger in SQL Server?

I want to insert the data from one table to another. The condition is if the first table having only record then only that record I need to insert into the another table.
I am trying Query :
INSERT INTO Customer_Map_Address(CustomerID, AddressID, IsBillingAddress)
SELECT [CustomerID], [ID], CAST('FALSE' as BIT) AS IsBillingAddress
FROM CustomerAddress Group By CustomerID, ID
having COUNT(CustomerID) = 1
It is Grouped by CustomerID and ID hence getting wrong output. I want to group only by CustomerID.
Thanks.
INSERT INTO dbo.Customer_Map_Address (CustomerID, AddressID, IsBillingAddress)
SELECT [CustomerID], MAX([Id]), 0 AS IsBillingAddress
FROM dbo.CustomerAddress
GROUP BY CustomerID
HAVING COUNT(*) = 1

How to remove duplicate rows in SQL Server?

Environment:
OS: Windows Server 2012 DataCenter
DBMS: SQL Server 2012
Hardware (VPS): Xeon E5530 4 cores + 4GB RAM
Question:
I have a large table with 140 million rows. Some rows are supposed to be duplicate so I want to remove such rows. For example:
id name value timestamp
---------------------------------------
001 dummy1 10 2015-7-27 10:00:00
002 dummy1 10 2015-7-27 10:00:00 <-- duplicate
003 dummy1 20 2015-7-27 10:00:00
The second row is deemed duplicate because it has identical name, value and timestamp regardless of different id with the first row.
Note: the first two rows are duplicate NOT because of all identical columns, but due to self-defined rules.
I tried to remove such duplication by using window function:
select
id, name, value, timestamp
from
(select
id, name, value, timestamp,
DATEDIFF(SECOND, lag(timestamp, 1) over (partition by name order by timestamp),
timestamp) [TimeDiff]
from table) tab
But after an hour of execution, the lock is used up and error was raised:
Msg 1204, Level 19, State 4, Line 2
The instance of the SQL Server Database Engine cannot obtain a LOCK resource at this time. Rerun your statement when there are fewer active users. Ask the database administrator to check the lock and memory configuration for this instance, or to check for long-running transactions.
How could I remove such duplicate rows in an efficient way?
What about using a cte? Something like this.
with DeDupe as
(
select id
, [name]
, [value]
, [timestamp]
, ROW_NUMBER() over (partition by [name], [value], [timestamp] order by id) as RowNum
from SomeTable
)
Delete DeDupe
where RowNum > 1;
If only thing is selection of non-duplicate rows from table, consider using this script
SELECT MIN(id), name, value, timestamp FROM table GROUP BY name, value, timestamp
If you need to delete duplicate rows:
DELETE FROM table WHERE id NOT IN ( SELECT MIN(id) FROM table GROUP BY name, value, timestamp)
or
DELETE t FROM table t INNER JOIN
table t2 ON
t.name=t2.name AND
t.value=t2.value AND
t.timestamp=t2.timestamp AND
t2.id<t.id
Try something like this - determine the lowest ID for each set of values, then delete rows that have an ID other than the lowest one.
Select Name, Value, TimeStamp, min(ID) as LowestID
into #temp1
From MyTable
group by Name, Value, TimeStamp
Delete MyTable
from MyTable a
inner join #temp1 b
on a.Name = b.Name
and a.Value = b.Value
and a.Timestamp = b.timestamp
and a.ID <> b.LowestID

TSQL Group By Issues

I have a TSQL query that I am trying to group data on. The table contains records of users and the access keys they hold such as site admin, moderator etc. The PK is on User and access key because a user can exist multiple times with different keys.
I am now trying to display a table of all users and in one column, all of the keys that user holds.
If bob had three separate records for his three separate access keys, result should only have One record for bob with all three of is access levels.
SELECT A.[FirstName],
A.[LastName],
A.[ntid],
A.[qid],
C.FirstName AS addedFirstName,
C.LastName AS addedLastName,
C.NTID AS addedNTID,
CONVERT(VARCHAR(100), p.TIMESTAMP, 101) AS timestamp,
(
SELECT k.accessKey,
k.keyDescription
FROM TFS_AdhocKeys AS k
WHERE p.accessKey = k.accessKey
FOR XML PATH ('key'), TYPE, ELEMENTS, ROOT ('keys')
)
FROM TFS_AdhocPermissions AS p
LEFT OUTER JOIN dbo.EmployeeTable as A
ON p.QID = A.QID
LEFT OUTER JOIN dbo.EmployeeTable AS C
ON p.addedBy = C.QID
GROUP BY a.qid
FOR XML PATH ('data'), TYPE, ELEMENTS, ROOT ('root');
END
I am trying to group the data by a.qid but its forcing me to group on every column in the select which will then not be unique so it will contain the duplicates.
Whats another approach to handle this?
Currently:
UserID | accessKey
123 | admin
123 | moderator
Desired:
UserID | accessKey
123 | admin
moderator
Recently, I was working on something and had a similar problem. Like your query, I had an inner 'for xml' with joins in the outer 'for xml'. It turned out it worked better if the joins were in the inner 'for xml'. The code is pasted below. I hope this helps.
Select
(Select Institution.Name, Institution.Id
, (Select Course.Courses_Id, Course.Expires, Course.Name
From
(Select Course.Courses_Id, Course.Expires, Courses.Name
From Institutions Course Course Join Courses On Course.Courses_Id = Courses.Id
Where Course.Institutions_Id = 31) As Course
For Xml Auto, Type, Elements) As Courses
From Institutions Institution
For Xml Auto, Elements, Root('Institutions') )
As I don't have the definitions for the other tables you have I just make a sample test data and you can follow this to answer yours.
Create statement
CREATE TABLE #test(UserId INT, AccessLevel VARCHAR(20))
Insert sample data
INSERT INTO #test VALUES(123, 'admin')
,(123, 'moderator')
,(123, 'registered')
,(124, 'moderator')
,(124, 'registered')
,(125, 'admin')
By using ROW_NUMBER() you can achieve what you need
;WITH C AS(
SELECT ROW_NUMBER() OVER(PARTITION BY UserId ORDER BY UserId) As Rn
,UserId
,AccessLevel
FROM #test
)
SELECT CASE Rn
WHEN 1 THEN UserId
ELSE NULL
END AS UserId
,AccessLevel
FROM C
Output
UserId AccessLevel
------ -----------
123 admin
NULL moderator
NULL registered
124 moderator
NULL registered
125 admin

how to set row number in sybase query

I have a select statemnt which will return results say 1000 using join with some 3 to 4 tables. My requirement is to have identity column in the resultset . Can anyone help me on this.
ex :
Result :
id name
-- ----
001 xxx
002 yyy
003 zzz
My requirment :
Rowid id name
1 -- ----
2 001 xxx
3 002 yyy
4 003 zzz
Like Row_number in sql , do we have anything here in sybase
In sybase there isn't row_number or something like that. Maybe temporary tables with identity column will help you?
Consider below example please.
select Rowid = identity(8), id, name
into #temtab
from tab
select Rowid, id, name
from #temtab
In the version of Sybase IQ I use, version Number() or ROW_NUMBER() functions exist. In my version you may use following:
select Number() rowid, id, name
from tab
or
select ROW_NUMBER() OVER (PARTITION BY name ORDER BY id) rowid, id, name
from tab
or
select ROW_NUMBER() OVER (ORDER BY id) rowid, id, name
from tab

Resources