AdventureWorks查询拼接日期与随机时间每行值相同问题求解
问题根因
SQL Server 中的RAND()函数如果不传入随机种子参数,属于查询级别的单次计算函数,整个查询执行过程中只会生成一次随机值,因此所有返回行的拼接时间部分完全相同。
修复方案
通过NEWID()为每行生成唯一的随机种子,触发每行独立计算随机值即可解决。提供两种可直接使用的实现方案:
方案1:对齐原写法逻辑修正
SELECT CONCAT( 'orderdate:', CONVERT(VARCHAR, OrderDate, 103), ' ', CONVERT(VARCHAR, OrderDate, 108), ' @newtime:', FORMAT(FLOOR(RAND(CHECKSUM(NEWID()))*24), '00'), ':', FORMAT(FLOOR(RAND(CHECKSUM(NEWID()))*60), '00'), ':', FORMAT(FLOOR(RAND(CHECKSUM(NEWID()))*60), '00'), ' order id :', SalesOrderID ) AS order_full_info FROM sales.salesorderheader soh
改动说明:
- 用
RAND(CHECKSUM(NEWID()))替换无参数的RAND():NEWID()会为每行生成唯一GUID,经CHECKSUM()转为整数作为随机种子,确保每行的随机值独立计算 - 简化了随机数范围计算:0-23的小时数直接用
FLOOR(RAND(...) *24)实现,0-59的分/秒数直接用FLOOR(RAND(...) *60)实现,无需额外加减操作 - 输出格式完全匹配你给出的预期结果,包含原有订单日期时间、新增随机时间、订单ID字段
方案2:更简洁的写法
可以直接通过秒偏移生成随机时间,无需分别拼接时分秒,代码更易维护:
SELECT CONCAT( 'orderdate:', CONVERT(VARCHAR, OrderDate, 103), ' ', CONVERT(VARCHAR, OrderDate, 108), ' @newtime:', CONVERT(VARCHAR, DATEADD(SECOND, ABS(CHECKSUM(NEWID())) % 86400, '00:00:00'), 108), ' order id :', SalesOrderID ) AS order_full_info FROM sales.salesorderheader soh
实现逻辑:
一天共86400秒,通过ABS(CHECKSUM(NEWID())) % 86400生成0-86399的随机秒数,追加到00:00:00上再转换为时分秒格式即可,性能也比三次调用RAND()更优。
内容的提问来源于stack exchange,提问作者Jagan Tirumalai
相关产品推荐
相关产品推荐

