Обновить таблицу SQL со случайным значением из другой таблицы

В Microsoft SQL Server 2008 у меня есть таблица с продуктами:

Идентификатор | Имя | DefaultImageId

И один с изображениями:

Идентификатор | ProductId | Б

Я хочу запустить инструкцию Update, которая обновляет DefaultImageId для всех записей в таблице Products со случайным идентификатором из таблицы "Изображения", которая связана с продуктом через столбец ProductId.

Может ли кто-нибудь помочь? Должен быть простым для любого SQL Champ (который, очевидно, не я).

Ответ 1

Вы можете сделать заказ на NEWID, чтобы получить случайное число для каждой строки вашего обновления.

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

Это было отмечено и добавлены комментарии, указывающие, что это не решает проблему. Я думаю, что путаница возникла из-за того, что люди не поняли, что первоначальный вопрос требует, чтобы для каждого продукта было выбрано случайное изображение, отсюда и пункт where с Product Id. Предоставили полный сценарий с набором данных ниже. Он добавляет пять продуктов и три изображения для каждого продукта. Затем случайным образом устанавливает идентификатор изображения по умолчанию для каждого продукта.

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

Ответ 2

Адресация проблемы @philreed с выбранным ответом:

Есть ли способ присвоить каждой обновляемой строке другое значение случайным образом выбранным из исходной таблицы?

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    

Ответ 3

Другое возможное решение

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

Ответ 4

Проверьте это.

Update Products
Set DefaultImageId = (
SELECT top 1 Id 
From Images 
Where 1=1
and Products.Id = Images.ProductId
ORDER BY NEWID()
)

Ответ 5

Попробуйте это (на AdventureWorks):

Он обновляет все строки таблицы лиц новым случайным именем из таблицы продуктов.

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

Или попробуйте аналогичный запрос на SQL Fiddle: http://sqlfiddle.com/#!3/8b719/1