Insert or update data using cte_results in SQL Server - sql

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

Related

sql server duplicate ID's update other columns

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

Big Query - Only insert if column value does not exist

Does Big Query support operations like "REPLACE INSERT" or something related to that?
If I run a query like this twice:
INSERT INTO table(column1) VALUES(1)
It'll create a duplicated row, is it possible to insert a row only if a column with the same value does not exist?
Thanks!
Below should make it
#standardSQL
INSERT INTO yourTable(column1)
SELECT value FROM (SELECT 1 AS value)
LEFT JOIN yourTable
ON column1 = value
WHERE column1 IS NULL
Does this work for you?
INSERT INTO table(column1)
WITH s AS (SELECT 1 src)
SELECT src FROM s WHERE NOT EXISTS (
SELECT * FROM table t WHERE t.column1 = s.src
)

How to Update Executed table result into the same table?

I have created a table tbl_Dist with Column names District and DistCode, there were many duplicate values in the District table so i have removed all the duplicates value using this statement:
select distinct District from tbl_Dist;
its done, but i am not getting how to update the results of the above executed query to the table tbl_Dist?
You can as the below:
-- Move temp table
SELECT DISTINCT District INTO TmpTable FROM tbl_Dist
-- Delete all data
DELETE FROM tbl_Dist
-- Insert data from temp table
INSERT INTO tbl_Dist
SELECT * FROM TmpTable
Updated
Firstly, run this query. You will have a temp table with distinct data of main table (tbl_Dist)
-- Move temp table
SELECT DISTINCT District INTO TmpTable FROM tbl_Dist
Then run the below query to delete all data
DELETE FROM tbl_Dist
Finally, run the below query to insert all distinct data to main table.
-- Insert data from temp table
INSERT INTO tbl_Dist
SELECT * FROM TmpTable
You need Delete not Update
;with cte as
(
Select row_number() over(partition by District order by (select null)) as rn,*
From yourtable
)
Delete from cte where Rn > 1
To check the records that will be deleted use this.
;with cte as
(
Select row_number() over(partition by District order by (select null)) as rn,*
From yourtable
)
Select * from cte where Rn > 1
If you want to keep this query you can keep it in a view the write an update query through that view.The table will be updated
try this script
DELETE FROM tbl_Dist
WHERE District = District
AND DistCode > DistCode

INSERT INTO SELECT from UPDATE

I need to select some values from a table to be updated, and then update them right away. Furthermore, I need to insert one new record in a table for each updated record. To select records and update I am using a structure like
UPDATE TableA SET SomeField = 1 OUTPUT RecordID FROM TableA WHERE RecordID IN
(
SELECT TOP #Something RecordID FROM TableA
)
Now, for the insert part, I would like to wrap the UPDATE statement into an INSERT INTO SELECT, thus taking advantage of the OUTPUT clause. However, SQL complains when I do
INSERT INTO TableA SELECT ( RecordID , GETDATE() ) FROM
(
UPDATE TableA SET SomeField = 1 OUTPUT RecordID FROM TableA WHERE RecordID IN
(
SELECT TOP #Something RecordID FROM TableA
)
)
Can't I do it all in one statement, even with the OUTPUT clause?
UPDATE TableA SET SomeField = 1
OUTPUT inserted.RecordID, GETDATE() into TableA (RecordID , DT)
FROM TableA
WHERE RecordID IN
(
SELECT TOP #Something RecordID FROM TableA
)
Just not sure - you're trying to insert updated rows again ?
It is posible to use output to insert the updated rows from one table to another:
However I cannot make that syntax you are using to work.
Please check out this link
Of course, you could try something like this:
INSERT INTO TableA (RecordID, Value)
SELECT RecordID, GETDATE()
FROM OPENQUERY(
yourserver,
'UPDATE TableA
SET SomeField = 1
OUTPUT inserted.RecordID
WHERE RecordID IN (SELECT TOP (5) RecordID FROM TableA)'
)
But there's a couple of issues with the approach:
You'd need to create a linked server yourserver.
The 'remote' query wouldn't be very swift.
You'd have hard time replacing TOP (5) with TOP (#Something). Actually you'd most probably have to turn the entire statement into a dynamic query. (That's right, you'd have to put the already dynamic UPDATE inside another dynamic query.)
I expect, with the last issue the one-statement limitation would finally be broken.
So, instead, why not have it like this:
DECLARE #tmpRecords TABLE (RecordID int);
UPDATE TableA
SET SomeField = 1
OUTPUT inserted.RecordID INTO #tmpRecords (RecordID)
WHERE RecordID IN (SELECT TOP (#Something) RecordID FROM TableA);
INSERT INTO TableA (RecordID, SomeDateColumn)
SELECT RecordID, GETDATE()
FROM #tmpRecords;

Delete records which are considered duplicates based on same value on a column and keep the newest

I would like to delete records which are considered duplicates based on them having the same value in a certain column and keep one which is considered the newest based on InsertedDate in my example below. I would like a solution which doesn't use a cursor but is set based. Goal: delete all duplicates and keep the newest.
The ddl below creates some duplicates. The records which need to be deleted are: John1 & John2 because they have the same ID as John3 and John3 is the newest record.
Also record John5 needs to be deleted because there's another record with ID = 3 and is newer (John6).
Create table dbo.TestTable (ID int, InsertedDate DateTime, Name varchar(50))
Insert into dbo.TestTable Select 1, '07/01/2009', 'John1'
Insert into dbo.TestTable Select 1, '07/02/2009', 'John2'
Insert into dbo.TestTable Select 1, '07/03/2009', 'John3'
Insert into dbo.TestTable Select 2, '07/03/2009', 'John4'
Insert into dbo.TestTable Select 3, '07/05/2009', 'John5'
Insert into dbo.TestTable Select 3, '07/06/2009', 'John6'
Just as an academic exercise:
with cte as (
select *, row_number() over (partition by ID order by InsertedDate desc) as rn
from TestTable)
delete from cte
where rn <> 1;
Most of the time the solution proposed by Sam performs much better.
This works:
delete t
from TestTable t
left join
(
select id, InsertedDate = max(InsertedDate) from TestTable
group by id
) as sub on sub.id = t.id and sub.InsertedDate = t.InsertedDate
where sub.id is null
If you have to deal with ties it gets a tiny bit trickier.