Update SQL table with random value from other tabl

2020-02-26 07:06发布

On Microsoft SQL Server 2008, I have a table with Products:

Id | Name | DefaultImageId

And one with Images:

Id | ProductId | Bytes

I want to run an Update statement, that updates the DefaultImageId on all records in the Products table with a random Id from the Images table that is related to the Product via the ProductId column.

Can anyone help out? Should be simple for any SQL Champ (Which is obviously not me)..

标签: sql-server
5条回答
成全新的幸福
2楼-- · 2020-02-26 07:25

Check this out.

Update Products
Set DefaultImageId = (
SELECT top 1 Id 
From Images 
Where 1=1
and Products.Id = Images.ProductId
ORDER BY NEWID()
)
查看更多
看我几分像从前
3楼-- · 2020-02-26 07:30

You can do an order by on a NEWID to get a random number for every row of your update.

UPDATE
    Products
SET
    DefaultImageId =
    (
        SELECT TOP 1
            Id
        FROM
            Images
        WHERE
            Images.ProductId = Products.Id
        ORDER BY
            NEWID()
    )

This has been down marked and comments added indicating it does not solve the problem. I think the confusion has come from where people have not realised the original question requests a random image be selected for each product, hence the where clause with Product Id. Have provided a full script with data set below. It adds five products and three images for each product. Then randomly sets the default image id for each product.

CREATE TABLE Products(Id INT, Name NVARCHAR(100), DefaultImageId INT NULL)

CREATE TABLE Images (Id INT, ProductId INT, Bytes VARBINARY(100))

INSERT INTO Products (Id, NAME, DefaultImageId) VALUES(1, 'A', NULL)
INSERT INTO Products (Id, NAME, DefaultImageId) VALUES(2, 'B', NULL)
INSERT INTO Products (Id, NAME, DefaultImageId) VALUES(3, 'C', NULL)
INSERT INTO Products (Id, NAME, DefaultImageId) VALUES(4, 'D', NULL)
INSERT INTO Products (Id, NAME, DefaultImageId) VALUES(5, 'E', NULL)

INSERT INTO Images (Id, ProductId, Bytes) VALUES(1, 1, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(2, 1, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(3, 1, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(4, 2, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(5, 2, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(6, 2, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(7, 3, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(8, 3, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(9, 3, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(10, 4, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(11, 4, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(12, 4, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(13, 5, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(14, 5, NULL)
INSERT INTO Images (Id, ProductId, Bytes) VALUES(15, 5, NULL)

UPDATE
    Products
SET
    DefaultImageId =
    (
        SELECT TOP 1
            Id
        FROM
            Images
        WHERE
            Images.ProductId = Products.Id
        ORDER BY
            NEWID()
    )

SELECT * FROM Products
查看更多
家丑人穷心不美
4楼-- · 2020-02-26 07:31

Try this one (on AdventureWorks):

It updates all rows of the person table with a new random name from the product table.

begin tran
--show initial state:
select top 25 * from person.person order by BusinessEntityID

update person.person
set 
FirstName = otherTable.Name
from 
(select BusinessEntityID, row_number() over (order by newid()) as row_num from person.person) p2
,(select ProductId, Name, row_number() over (order by newid()) as row_num from production.product) as otherTable
where 
person.person.BusinessEntityID=p2.BusinessEntityID 
and (p2.row_num%500)=(otherTable.row_num%500) -- deal with tables with different rowcount

--check results:
select top 25 * from person.person order by BusinessEntityID

rollback tran

Or try a similar query on SQL Fiddle: http://sqlfiddle.com/#!3/8b719/1

查看更多
劳资没心,怎么记你
5楼-- · 2020-02-26 07:32

Another possible solution

UPDATE
    Products
SET
    DefaultImageId =
    (
        SELECT TOP 1
            Id
        FROM
            Images
        ORDER BY
            NEWID(), Products.Id
    )
查看更多
ら.Afraid
6楼-- · 2020-02-26 07:40

Addressing @philreed's issue with the selected answer:

Is there a way to assign each row being updated with a different value randomly chosen from the source table?

UPDATE Products
SET DefaultImageId = t2.Id
FROM Products t1
CROSS APPLY (
    SELECT TOP 1 Id
    FROM Images
    WHERE t1.Id = t1.Id
    ORDER BY newid()
    ) t2    
查看更多
登录 后发表回答