如何在SQL的SELECT语句中为每行分配不同的随机值?
解决T1每行获取T2不同随机值的问题
你说得完全正确,原代码里的子查询只会执行一次——数据库会先跑完子查询拿到一个随机值,再把这个值重复填充到T1的每一行里。要实现每行都从T2取不同的随机值,我们可以通过让子查询针对T1的每一行单独执行来解决,下面给你两种实用的方案:
方法一:使用CROSS APPLY(推荐,适用于SQL Server)
SELECT T1.COL1, T2_RAND.COL2 FROM T1 CROSS APPLY ( SELECT TOP 1 COL2 FROM T2 ORDER BY NEWID() ) AS T2_RAND
CROSS APPLY会把T1的每一行和子查询的结果做关联,子查询会为T1的每一行单独运行一次,这样每次都会重新对T2做随机排序并取第一行,自然每行都能得到不同的随机值。
方法二:行号关联法(适配更多场景)
如果你的业务有特殊限制,也可以通过给两行集添加随机行号的方式关联:
WITH T1_RN AS ( SELECT COL1, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RN FROM T1 ), T2_RAND AS ( SELECT COL2, ROW_NUMBER() OVER (ORDER BY NEWID()) AS RN FROM T2 ) SELECT T1_RN.COL1, T2_RAND.COL2 FROM T1_RN JOIN T2_RAND ON T1_RN.RN % (SELECT COUNT(*) FROM T2) = T2_RAND.RN - 1
这个方法通过给T1生成连续行号,给T2生成随机行号,再用取模的方式让T1每行对应T2的随机行,适合需要重复利用T2值但保证随机性的场景。
另外要注意,NEWID()是SQL Server专属的随机函数,如果是其他数据库(比如MySQL用RAND(),PostgreSQL用RANDOM()),需要替换成对应数据库的随机函数,语法也要做调整(比如PostgreSQL用LATERAL JOIN代替CROSS APPLY)。
内容的提问来源于stack exchange,提问作者Cthulhu
相关产品推荐
相关产品推荐

