Обновление таблицы со случайными данными с помощью NEWID () не работает - PullRequest
5 голосов
/ 08 января 2010

SQL SERVER 2000:

У меня есть таблица с тестовыми данными (около 100000 строк), я хочу обновить значение столбца из другой таблицы с некоторыми случайными данными из другой таблицы. Согласно этот вопрос , вот что я пытаюсь:

UPDATE testdata
SET type = (SELECT TOP 1 id FROM testtypes ORDER BY CHECKSUM(NEWID()))

-- or even
UPDATE testdata
SET type = (SELECT TOP 1 id FROM testtypes ORDER BY NEWID())

Тем не менее, поле "type" по-прежнему имеет одинаковое значение для всех строк; Есть идеи, что я делаю не так?

[ 1011 * EDIT *] Я ожидаю, что этот запрос будет возвращать одно значение для каждой строки, но это не так:

SELECT testdata.id, (SELECT TOP 1 id FROM testtypes ORDER BY CHECKSUM(NEWID())) type
FROM testdata

-- however seeding a rand value works
SELECT testdata.id, (SELECT TOP 1 id FROM testtypes ORDER BY CHECKSUM(NEWID()) + RAND(testdata.id)) type
FROM testdata

Ответы [ 2 ]

4 голосов
/ 08 января 2010

Ваша проблема: вы выбираете только одно значение , а затем обновляете все столбцы этим единственным значением.

Для того, чтобы действительно начать рандомизацию, вам нужно использовать пошаговый / циклический подход - я пробовал это в SQL Server 2008, но я думаю, что он должен работать и в SQL Server 2000:

-- declare a temporary TABLE variable in memory
DECLARE @Temporary TABLE (ID INT)

-- insert all your ID values (the PK) into that temporary table
INSERT INTO @Temporary SELECT ID FROM dbo.TestData

-- check to see we have the values
SELECT COUNT(*) AS 'Before the loop' FROM @Temporary 

-- pick an ID from the temporary table at random    
DECLARE @WorkID INT
SELECT TOP 1 @WorkID = ID FROM @Temporary ORDER BY NEWID()

WHILE @WorkID IS NOT NULL
BEGIN
    -- now update exactly one row in your base table with a new random value
    UPDATE dbo.TestData
    SET [type] = (SELECT TOP 1 id FROM dbo.TestTypes ORDER BY NEWID())
    WHERE ID = @WorkID

    -- remove that ID from the temporary table - has been updated 
    DELETE FROM @Temporary WHERE ID = @WorkID

    -- first set @WorkID back to NULL and then pick a new ID from 
    -- the temporary table at random        
    SET @WorkID = NULL
    SELECT TOP 1 @WorkID = ID FROM @Temporary ORDER BY NEWID()
END

-- check to see we have no more IDs left
SELECT COUNT(*) AS 'After the update loop' FROM @Temporary 
2 голосов
/ 08 января 2010

вам нужно применить расчет на строку в выборе новых идентификаторов.

это бы сработало

UPDATE testdata
SET type = (SELECT TOP 1 id FROM testtypes ORDER BY outerTT*CHECKSUM(NEWID()))
FROM testtypes outerTT
...