使用 NEWID() 用随机数据更新表不起作用

发布于 2024-08-17 03:34:08 字数 796 浏览 4 评论 0原文

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”字段仍然具有相同的值;有什么想法我做错了什么吗?

[编辑] 我希望此查询为每一行返回一个不同的值,但事实并非如此:

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

SQL SERVER 2000:

I have a table with test data (about 100000 rows), I want to update a column value from another table with some random data from another table. According to this question, This is what I am trying:

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())

However, the "type" field is still with the same value for all rows; Any ideas what Am I doing wrong?

[EDIT]
I would expect this query to return one different value for each row, but it doesn't:

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听风吹 2024-08-24 03:34:08

您的问题是:您仅选择一个单个值,然后使用该单个值更新所有列

为了真正实现随机化,您需要执行逐步/循环方法 - 我在 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 

Your problem is: you are selecting only a single value and then updating all columns with that one single value.

In order to really get a randomization going, you need to do a step-by-step / looping approach - I tried this in SQL Server 2008, but I think it should work in SQL Server 2000 as well:

-- 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 
因为看清所以看轻 2024-08-24 03:34:08

您需要在选择新 id 时强制执行每行计算..

这可以解决问题

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

you need to enforce a per row calculation in the selection of the new ids ..

this would do the trick

UPDATE testdata
SET type = (SELECT TOP 1 id FROM testtypes ORDER BY outerTT*CHECKSUM(NEWID()))
FROM testtypes outerTT
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文