Reputation: 113
I'm trying to insert invoice numbers from one database to another. The new database, invoiceNo is the primary key. There are duplicate invoice numbers from the original database. I found the duplicates using
SELECT SERIAL_NO,
COUNT(*) as cnt
FROM HISTORY_INCIDENTS
group by SERIAL_NO having COUNT(*) > 1
order by COUNT(*) desc
I would like to place a -1 at the end of the second invoice so they will be unique. Not sure how to do this is SQL
Upvotes: 1
Views: 118
Reputation: 3284
I think this will work.
I used the ROW_NUMBER() function to calculate the number of times a serial number occurred in a inner derived table. In the main query, I make decisions on how to craft the new serial number based on the number of occurrences I found.
PS: done without an SQL editor.
SELECT
SERIAL_NO
,SERIAL_NO + CASE WHEN [SERIAL_NO_Occurrence] > 1 THEN '-' + CAST([SERIAL_NO_Occurrence]-1 AS VARCHAR) ELSE '' END AS [SERIAL_NO_New]
FROM (
-- inner derived table to select number of occurrences of each serial number
SELECT SERIAL_NO
,ROW_NUMBER() OVER (
PARTITION BY SERIAL_NO
ORDER BY SERIAL_NO -- you should also have a PK field here to have deterministic results I think
) AS [SERIAL_NO_Occurrence]
FROM HISTORY_INCIDENTS
) AS T1;
Upvotes: 0
Reputation: 18749
You could use a CTE like this...
;
WITH cteDups
AS ( SELECT SERIAL_NO ,
RN = ROW_NUMBER() OVER
( PARTITION BY SERIAL_NO ORDER BY SERIAL_NO )
FROM HISTORY_INCIDENTS
)
SELECT CASE RN
WHEN 2 THEN SERIAL_NO + '-1'
ELSE SERIAL_NO
END AS SERIAL_NO
FROM cteDups
see the fiddle. This will create a row number of 2 when there's a duplicate, you can then use a CASE
to check for any 2's, and assign the -1 to that record.
EDIT: based on comment
DECLARE @HISTORY_INCIDENTS TABLE ( SERIAL_NO INT );
DECLARE @NewHISTORY_INCIDENTS TABLE ( SERIAL_NO VARCHAR(10) );
INSERT INTO @HISTORY_INCIDENTS
( SERIAL_NO )
VALUES ( 1 );
INSERT INTO @HISTORY_INCIDENTS
( SERIAL_NO )
VALUES ( 2 );
INSERT INTO @HISTORY_INCIDENTS
( SERIAL_NO )
VALUES ( 2 );
INSERT INTO @HISTORY_INCIDENTS
( SERIAL_NO )
VALUES ( 2 );
;
WITH cteDups
AS ( SELECT SERIAL_NO ,
RN = ROW_NUMBER() OVER ( PARTITION BY SERIAL_NO
ORDER BY SERIAL_NO )
FROM @HISTORY_INCIDENTS
)
INSERT INTO @NewHISTORY_INCIDENTS
( SERIAL_NO
)
SELECT CASE RN
WHEN 2 THEN CAST(SERIAL_NO AS VARCHAR(10)) + '-1'
ELSE CAST(SERIAL_NO AS VARCHAR(10))
END AS SERIAL_NO
FROM cteDups
SELECT SERIAL_NO
FROM @NewHISTORY_INCIDENTS
Upvotes: 2