Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Update table using random of multiple values in other table

Consider this data:

CREATE TABLE #Data (DataID INT, Code VARCHAR(2), Prefix VARCHAR(3))

INSERT INTO #Data (DataID, Code)
VALUES (1, 'AA')
, (2, 'AA')
, (3, 'AA')
, (4, 'AA')
, (5, 'AA')
, (6, 'AA')

CREATE TABLE #Prefix (Code VARCHAR(2), Prefix VARCHAR(3))

INSERT INTO #Prefix (Code, Prefix)
VALUES ('AA', 'ABC')
, ('AA', 'DEF')
, ('AA', 'GHI')
, ('AA', 'JKL')

I want to set the Prefix value in #Data to be a random Prefix from #Prefix with a matching Code.

Using a straight inner join just results in one value being used:

UPDATE D
SET Prefix = P.Prefix
FROM #Data AS D
INNER JOIN #Prefix AS P ON D.Code = P.Code

From reading other questions on here, NEWID() is recommended as a way of randomly ordering something. Changing the join to:

SELECT TOP 1 subquery ordering by NEWID() 

still only selects a single value (though random each time) for every row:

UPDATE D
SET Prefix = (SELECT TOP 1 P.Prefix FROM #Prefix AS P WHERE P.Code = D.Code ORDER BY NEWID())
FROM #Data AS D

So, I'm not sure how to get a random prefix for each data entry from a single update statement. I could probably do some kind of loop through the #Data table, but I avoid ever touching loops in SQL and I'm sure that would be slow. The actual application of this will be on tens of thousands of records, with hundreds of prefixes for dozens of codes.

like image 993
John Straka Avatar asked May 29 '15 14:05

John Straka


People also ask

How do you UPDATE a table based on values from another table?

In this article, we will see, how to update from one table to another table based on ID match. We can update the table using UPDATE statement in SQL. The update statement is always followed by the SET command. The SET command is used to specify which columns and values need to be updated in a table.

Can we UPDATE multiple tables in a single UPDATE statement?

For instance, updating 2 different tables together in a single query/statement. This involves the use of the BEGIN TRANSACTION clause and the COMMIT clause. The individual UPDATE clauses are written in between the former ones to execute both the updates simultaneously.

Can we UPDATE multiple tables using UPDATE command?

In SQL Server, we can join two or more tables, but we cannot update the data of multiple tables in a single UPDATE statement.


1 Answers

This is how to do it:

UPDATE d SET Prefix = ca.Prefix
FROM #Data d
CROSS APPLY(SELECT TOP 1 Prefix 
            FROM #Prefix p 
            WHERE d.DataID = d.DataID AND p.Code = d.Code ORDER BY NEWID()) ca

Notice d.DataID = d.DataID. This is here to force Sql Server engine to reevaluate subquery for each row in #Data table.

like image 176
Giorgi Nakeuri Avatar answered Dec 11 '22 09:12

Giorgi Nakeuri