Hi There,
I'm trying to write a query that sets a batch of rows to have a single uniquely generated ID on the fly. Tried lots of things and just can't get it right.
Below are sample scripts to create the table and insert some test data along with two update queries that do not give me the desired results. I understand why they do not achieve what I'm looking for they are really there to show the kind of things I have tried.
Here is an image of what i want the reults to look like. All ref numbers that match have the same uniquely generated ID. Any input would be appreciated, i might have to go a different route and happy to do so if there is a better option. Thanks for looking.
-- CODE SAMPLES
CREATE TABLE ##temp (
ref VARCHAR(MAX),
batch_ID VARCHAR(MAX)
);
INSERT INTO ##temp (ref) values(1)
INSERT INTO ##temp (ref) values(1)
INSERT INTO ##temp (ref) values(1)
INSERT INTO ##temp (ref) values(2)
INSERT INTO ##temp (ref) values(2)
INSERT INTO ##temp (ref) values(2)
INSERT INTO ##temp (ref) values(3)
INSERT INTO ##temp (ref) values(4)
INSERT INTO ##temp (ref) values(5)
INSERT INTO ##temp (ref) values(5)
select * from ##temp
-- DELETE from ##temp
-- update queries
--1
DECLARE @random_guid VARCHAR(250);
SET @random_guid = NEWID()
update ##temp set batch_id = @random_guid where ref=REF
--2
update ##temp set batch_id = NEWID() where ref=REF
DROP TABLE ##temp
September 10, 2020 at 12:42 pm
I did something similar once. We had a version table. Everything did an insert to the version table to get a version ID, then that ID was used across all other inserts to other tables.
"The credit belongs to the man who is actually in the arena, whose face is marred by dust and sweat and blood"
- Theodore Roosevelt
Author of:
SQL Server Execution Plans
SQL Server Query Performance Tuning
September 10, 2020 at 1:49 pm
Why not just use a SEQUENCE?
--Jeff Moden
Change is inevitable... Change for the better is not.
September 10, 2020 at 3:02 pm
As general issues go does this require ##temp to have global scope? Also, why make the variables varchar(max)? I got it to work like this
drop table if exists #temp;
go
CREATE TABLE #temp (
ref int not null,
batch_ID CHAR(36));
INSERT INTO #temp(ref) values
(1),(1),(1),(2),(2),(2),(3),(4),(5),(5);
update t
set batch_ID=rt.nid
from #temp t
join
(select distinct ref, newid() nid from #temp) rt on t.ref=rt.ref;
Output
refbatch_ID
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
2F245A746-60C0-4FBA-B168-74ACB034243C
2F245A746-60C0-4FBA-B168-74ACB034243C
2F245A746-60C0-4FBA-B168-74ACB034243C
3AAF89776-C887-4245-B9DB-3CE47311E8A2
49DAD6FD8-D5AE-493C-AB94-276B2C73C30A
5AC0B546A-F21B-46C3-9CDB-07FF58E7FBE6
5AC0B546A-F21B-46C3-9CDB-07FF58E7FBE6
Aus dem Paradies, das Cantor uns geschaffen, soll uns niemand vertreiben können
September 10, 2020 at 3:56 pm
As general issues go does this require ##temp to have global scope? Also, why make the variables varchar(max)? I got it to work like this
drop table if exists #temp;
go
CREATE TABLE #temp (
ref int not null,
batch_ID CHAR(36));
INSERT INTO #temp(ref) values
(1),(1),(1),(2),(2),(2),(3),(4),(5),(5);
update t
set batch_ID=rt.nid
from #temp t
join
(select distinct ref, newid() nid from #temp) rt on t.ref=rt.ref;Output
refbatch_ID
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
2F245A746-60C0-4FBA-B168-74ACB034243C
2F245A746-60C0-4FBA-B168-74ACB034243C
2F245A746-60C0-4FBA-B168-74ACB034243C
3AAF89776-C887-4245-B9DB-3CE47311E8A2
49DAD6FD8-D5AE-493C-AB94-276B2C73C30A
5AC0B546A-F21B-46C3-9CDB-07FF58E7FBE6
5AC0B546A-F21B-46C3-9CDB-07FF58E7FBE6
Just a performance tip... You might want to use a WHERE EXISTS instead of a SELECT DISTINCT with a join.
--Jeff Moden
Change is inevitable... Change for the better is not.
September 10, 2020 at 5:50 pm
As general issues go does this require ##temp to have global scope? Also, why make the variables varchar(max)? I got it to work like this
drop table if exists #temp;
go
CREATE TABLE #temp (
ref int not null,
batch_ID CHAR(36));
INSERT INTO #temp(ref) values
(1),(1),(1),(2),(2),(2),(3),(4),(5),(5);
update t
set batch_ID=rt.nid
from #temp t
join
(select distinct ref, newid() nid from #temp) rt on t.ref=rt.ref;Output
refbatch_ID
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
112EAAEFE-EC57-455A-ACCE-A18F3B6415D8
2F245A746-60C0-4FBA-B168-74ACB034243C
2F245A746-60C0-4FBA-B168-74ACB034243C
2F245A746-60C0-4FBA-B168-74ACB034243C
3AAF89776-C887-4245-B9DB-3CE47311E8A2
49DAD6FD8-D5AE-493C-AB94-276B2C73C30A
5AC0B546A-F21B-46C3-9CDB-07FF58E7FBE6
5AC0B546A-F21B-46C3-9CDB-07FF58E7FBE6
Keep in mind that'll update all the batch id's every time which might not be intended or a good idea on a large table. Adding a WHERE batch_ID IS NULL on the self join should fix that.
Keep in mind that'll update all the batch id's every time which might not be intended or a good idea on a large table. Adding a WHERE batch_ID IS NULL on the self join should fix that.
Something like this?
update t
set batch_ID=rt.nid
from #temp t
join (select distinct ref, newid() nid from #temp) rt on t.ref=rt.ref
where batch_ID is null;
Aus dem Paradies, das Cantor uns geschaffen, soll uns niemand vertreiben können
September 11, 2020 at 8:28 am
Thanks guys really appreciate your input and great solutions.
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply