sql server duplicate ID's update other columns - sql

I was working on a task to update columns which have duplicate ID's in a column
how can we update column only DrugLabelName ? i need to update old_drug_name with new_drug_name using the duplicate ID 00004029830 ?
Please advise

If you want all rows with the same id to have the same name, you can use window functions:
with toupdate as (
select t.*,
first_value(druglabelname) over (partition by id order by intid desc) as new_druglabelname
from t
)
update toupdate
set druglabelname = new_druglabelname
where druglabelname <> new_druglabelname;

How about?
CREATE TABLE tbl
(INTid int
,ID varchar (20)
,DrugLabelName varchar(200)
)
INSERT tbl (INTid, ID, DrugLabelName)
SELECT 137272, '00004029830', 'old_drug_name'
INSERT tbl (INTid, ID, DrugLabelName)
SELECT 1668177, '00004029830', 'New_drug_name'
INSERT tbl (INTid, ID, DrugLabelName)
SELECT 1668178, '00004029831', 'Other_drug_name'
GO
UPDATE t
SET DrugLabelName = x.DrugLabelName
FROM tbl AS t
INNER JOIN tbl as x
ON t.ID = x.id
AND x.INTid > t.INTid
SELECT *
FROM tbl
DROP TABLE tbl

Related

Insert values for whole column in SQL Server

Is there any way to insert different values for specific column, not whole row in SQL Server.
Classic UPDATE SET would set all to same value.
For example I want to set some int values to Ranking column for each of 3 rows, without dropping them and doing complete new insert into.
Use row_number()
update a set ranking =rn from tablename a join
(select id,name, row_number() over(order by id) as rn
from tablename) b on a.id=b.id
do update
update tabale
set ranking= your_va
with cte as
(
select * ,row_number() over(order by id) rn
) update cte set ranking=rn where id<=3
What value do you want to set ranking to?
Just any value:
update mytable set ranking = id;
Certain values:
update mytable set ranking =
case name
when 'Positive' then 1
when 'Neutral' then 2
when 'Negative' then 3
else 4
end;

Oracle: UPDATE with ORDER BY [duplicate]

I want to populate a table column with a running integer number, so I'm thinking of using ROWNUM. However, I need to populate it based on the order of other columns, something like ORDER BY column1, column2. That is, unfortunately, not possible since Oracle does not accept the following statement:
UPDATE table_a SET sequence_column = rownum ORDER BY column1, column2;
Nor the following statement (an attempt to use WITH clause):
WITH tmp AS (SELECT * FROM table_a ORDER BY column1, column2)
UPDATE tmp SET sequence_column = rownum;
So how do I do it using an SQL statement and without resorting to cursor iteration method in PL/SQL?
This should work (works for me)
update table_a outer
set sequence_column = (
select rnum from (
-- evaluate row_number() for all rows ordered by your columns
-- BEFORE updating those values into table_a
select id, row_number() over (order by column1, column2) rnum
from table_a) inner
-- join on the primary key to be sure you'll only get one value
-- for rnum
where inner.id = outer.id);
OR you use the MERGE statement. Something like this.
merge into table_a u
using (
select id, row_number() over (order by column1, column2) rnum
from table_a
) s
on (u.id = s.id)
when matched then update set u.sequence_column = s.rnum
UPDATE table_a
SET sequence_column = (select rn
from (
select rowid,
row_number() over (order by col1, col2)
from table_a
) x
where x.rowid = table_a.rowid)
But that won't be very fast and as Damien pointed out, you have to re-run this statement each time you change data in that table.
First Create a sequence :
CREATE SEQUENCE SEQ_SLNO
START WITH 1
MAXVALUE 999999999999999999999999999
MINVALUE 1
NOCYCLE
NOCACHE
NOORDER;
after that Update the table using the sequence:
UPDATE table_name
SET colun_name = SEQ_SLNO.NEXTVAL;
A small correction just add AS RN :
UPDATE table_a
SET sequence_column = (select rn
from (
select rowid,
row_number() over (order by col1, col2) AS RN
from table_a
) x
where x.rowid = table_a.rowid)

Insert or update data using cte_results in SQL Server

I have a query having cte with number of columns, I want to insert a record if ID from the results of that query does not exist in table that I am inserting, or if the ID exists I want to update data using that ID.
So far I have tried this:
WITH cte_base as(
SELECT DISTINCT ID, statusID
FROM testtable
)
SELECT *
FROM cte_base
IF EXISTS(SELECT * FROM Newtable WHERE EXISTS (SELECT ID FROM cte_base))
UPDATE newtable
SET statusID = 2
WHERE Newtable.ID = cte_base.ID
ELSE
INSERT INTO newtable(ID, statusID)
SELECT ID, statusID
FROM cte_base
WHERE Newtable.ID <> cte_base.ID
I have to run this query against live data, hence I would like to know if my logic is correct.
Basic merge example based on your provided code.
MERGE INTO NewTable AS T
USING
(
SELECT DISTINCT ID,statusID
FROM testtable
) AS S
ON S.ID = T.ID
WHEN MATCHED THEN SET
T.StatusID = 2
WHEN NOT MATCHED INSERT (ID,statusID)
VALUES (S.ID,S.statusID)
;
What are you trying to do?
EXISTS (SELECT ID FROM cte_base)
If cte_base has any records that will be true every time
That is no different than
SELECT DISTINCT ID, statusID
FROM testtable
And will be true every time if there are any records in testtable

Send faulty rows to other table

I have a table with many columns in which I have to find the duplicate based on one column.
I.e. if I found duplicate customer_name in the Customer_name then
I have to remove all repeating from the source table.
Send all those rows to other table with same structure.
If you have two tables like this:
CREATE TABLE t1 (ID int, customerName varchar(64))
CREATE TABLE t2 (ID int, customerName varchar(64))
You can make something like this: (The ID column is for just to have a base for the deceision what to keep, you can change it as you need)
--First Copy
WITH CTE_T1
AS
(
SELECT
ID,
customerName,
ROW_NUMBER() OVER(PARTITION BY customerName ORDER BY ID) as OrderOfCustomer
FROM
t1
)
INSERT INTO t2
SELECT ID, customerName FROM cte_T1
WHERE OrderOfCustomer > 1;
--Then Delete
WITH CTE_T1
AS
(
SELECT
ID,
customerName,
ROW_NUMBER() OVER(PARTITION BY customerName ORDER BY ID) as OrderOfCustomer
FROM
t1
)
DELETE FROM CTE_T1
WHERE OrderOfCustomer > 1
Here is an SQLFiddle to show how it works.
I guess each row has a unique Id primary key.
This inserts into your duplicate rows table :
Insert into duplicateRowsTable
select * from myTable t1
where (select count(*) from myTable t2 where t1.customerId = t2.customerId) > 1
You delete from the duplicateRowsTable the good rows:
delete from duplicatesTable
where --this is not the faulty row for each customerId
finally you delete from your first table :
delete from myTable
where id IN (select id from duplicatesTable)
Try this:
For moving duplicates
INSERT Into DuplicatesTable
SELECT *
FROM
(SELECT *, ROW_NUMBER() OVER(PARTITION BY Customer_name ORDER BY Customer_name) As RowID,
FROM SourceTable) as temp
WHERE RowID > 1
For deteting:
WITH TableCTE
AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY Customer_name ORDER BY Customer_name) AS RowID
FROM SourceTable
)
DELETE
FROM TableCTE
WHERE RowID> 1

Oracle: Updating a table column using ROWNUM in conjunction with ORDER BY clause

I want to populate a table column with a running integer number, so I'm thinking of using ROWNUM. However, I need to populate it based on the order of other columns, something like ORDER BY column1, column2. That is, unfortunately, not possible since Oracle does not accept the following statement:
UPDATE table_a SET sequence_column = rownum ORDER BY column1, column2;
Nor the following statement (an attempt to use WITH clause):
WITH tmp AS (SELECT * FROM table_a ORDER BY column1, column2)
UPDATE tmp SET sequence_column = rownum;
So how do I do it using an SQL statement and without resorting to cursor iteration method in PL/SQL?
This should work (works for me)
update table_a outer
set sequence_column = (
select rnum from (
-- evaluate row_number() for all rows ordered by your columns
-- BEFORE updating those values into table_a
select id, row_number() over (order by column1, column2) rnum
from table_a) inner
-- join on the primary key to be sure you'll only get one value
-- for rnum
where inner.id = outer.id);
OR you use the MERGE statement. Something like this.
merge into table_a u
using (
select id, row_number() over (order by column1, column2) rnum
from table_a
) s
on (u.id = s.id)
when matched then update set u.sequence_column = s.rnum
UPDATE table_a
SET sequence_column = (select rn
from (
select rowid,
row_number() over (order by col1, col2)
from table_a
) x
where x.rowid = table_a.rowid)
But that won't be very fast and as Damien pointed out, you have to re-run this statement each time you change data in that table.
First Create a sequence :
CREATE SEQUENCE SEQ_SLNO
START WITH 1
MAXVALUE 999999999999999999999999999
MINVALUE 1
NOCYCLE
NOCACHE
NOORDER;
after that Update the table using the sequence:
UPDATE table_name
SET colun_name = SEQ_SLNO.NEXTVAL;
A small correction just add AS RN :
UPDATE table_a
SET sequence_column = (select rn
from (
select rowid,
row_number() over (order by col1, col2) AS RN
from table_a
) x
where x.rowid = table_a.rowid)