我是新来的sql服务器。我需要生成从给定日期范围中选择的随机日期。 像雇员的雇用日期应该在2011-01-01
和2011-12-31
之间的任何地方。生成的日期应该随机地插入1000行的表中。如何在给定范围之间插入1000个随机日期?
任何人都可以引导我与我的查询?
我是新来的sql服务器。我需要生成从给定日期范围中选择的随机日期。 像雇员的雇用日期应该在2011-01-01
和2011-12-31
之间的任何地方。生成的日期应该随机地插入1000行的表中。如何在给定范围之间插入1000个随机日期?
任何人都可以引导我与我的查询?
我有写你这个简单的函数返回的日期范围之间的随机日期:
create function date_rand (@fromDate date, @toDate date) returns date
as
begin
declare @days_between int
declare @days_rand int
set @days_between = datediff(day,@fromDate,@toDate)
set @days_rand = cast(RAND()*10000 as int) % @days_between
return dateadd(day, @days_rand, @fromDate)
end
调用的函数:
select dbo.date_rand('1/1/2001', '10/1/2001')
你可以用一排发电机组合功能:
;WITH Nbrs_3(n) AS (SELECT 1 UNION SELECT 0),
Nbrs_2(n) AS (SELECT 1 FROM Nbrs_3 n1 CROSS JOIN Nbrs_3 n2),
Nbrs_1(n) AS (SELECT 1 FROM Nbrs_2 n1 CROSS JOIN Nbrs_2 n2),
Nbrs_0(n) AS (SELECT 1 FROM Nbrs_1 n1 CROSS JOIN Nbrs_1 n2),
Nbrs (n) AS (SELECT 1 FROM Nbrs_0 n1 CROSS JOIN Nbrs_0 n2)
SELECT dbo.date_rand('1/1/2001', '10/1/2001')
FROM (SELECT ROW_NUMBER() OVER (ORDER BY n)
FROM Nbrs) D (n)
WHERE n <= 1000
EDITED
来产生随机数使用:
RAND(CHECKSUM(NEWID()))
代替RAND()
EDITED II
函数返回内的“无效使用副作用的操作者的 '兰特'功能'错误。这是因为我们不能使用像RAND()或NEWID()这样的非确定性函数。
一种解决方法是create a view like:
create view myRandomNumber as
select cast(RAND(CHECKSUM(NEWID()))*1000 as int) as new_rand
,然后用它在功能上:
...
select @days_rand = new_rand % @days_between from myRandomNumber
...
或简单的不使用的功能和选择写expresion。我已经写了一个函数只哟解释一步一步的解决方案。
declare @fromdate date
declare @todate date
set @fromdate = '1/1/2001'
set @todate = '10/1/2001'
;WITH Nbrs_3(n) AS (SELECT 1 UNION SELECT 0),
Nbrs_2(n) AS (SELECT 1 FROM Nbrs_3 n1 CROSS JOIN Nbrs_3 n2),
Nbrs_1(n) AS (SELECT 1 FROM Nbrs_2 n1 CROSS JOIN Nbrs_2 n2),
Nbrs_0(n) AS (SELECT 1 FROM Nbrs_1 n1 CROSS JOIN Nbrs_1 n2),
Nbrs (n) AS (SELECT 1 FROM Nbrs_0 n1 CROSS JOIN Nbrs_0 n2)
SELECT
dateadd(day,
cast(RAND(CHECKSUM(NEWID()))*1000 as int) %
datediff(day,@fromDate,@toDate),
@fromDate)
FROM (SELECT ROW_NUMBER() OVER (ORDER BY n)
FROM Nbrs) D (n)
WHERE n <= 1000
declare @FromDate date = '2011-01-01'
declare @ToDate date = '2011-12-31'
select dateadd(day,
rand(checksum(newid()))*(1+datediff(day, @FromDate, @ToDate)),
@FromDate)
嗯,我知道这是一个老问题,但它是从一个较新的一个链接所以...这里是我的2美分:
基于这些前提,我相信实际上并不需要在表中存储1000个随机日期,但只能存储相关日期并只选择多少行以及以任何顺序需要。
首先,将数据存储在表格中。您可以使用Tally table来创建相关的日期范围。
Tally表是包含一系列数字的表格。为了论证的缘故,假设您已经创建了一个数字在0到1,000,000之间的计数表。
You can check this link为创造一个最好的方式,我个人喜欢这种方法:
-- create the tally table
SELECT TOP 100000 IDENTITY (int ,0, 1) as num
INTO Tally
FROM sys.sysobjects
CROSS JOIN sys.all_columns
现在,你有帐簿桌,这是相当简单的创建日历:
DECLARE @FromDate datetime = GETDATE(),
@ToDate datetime = DATEADD(YEAR, 1, GETDATE()) -- a year from now in my example
;With CalendarCTE AS
(
SELECT DATEADD(DAY, num, @FromDate) As caneldarDate
FROM Tally
WHERE num < DATEDIFF(DAY, @FromDate, @ToDate)
)
现在你有日历和计数表,使用它们可以非常简单地以任意顺序获取任意数量的记录。 千个随机排列的日期?没问题:
SELECT TOP 1000 caneldarDate
FROM CalendarCTE c
CROSS JOIN Tally t
WHERE t.num < 1000
ORDER BY NEWID()
完整的脚本,其中包括创建和删除理货的议席超过一秒来执行:
-- create the tally table
SELECT TOP 100000 IDENTITY (int ,0, 1) as num
INTO Tally
FROM sys.sysobjects
CROSS JOIN sys.all_columns
-- crealte the calendar cte:
DECLARE @FromDate datetime = GETDATE(),
@ToDate datetime = DATEADD(YEAR, 1, GETDATE())
;With CalendarCTE AS
(
SELECT DATEADD(DAY, num, @FromDate) As caneldarDate
FROM Tally
WHERE num < DATEDIFF(DAY, @FromDate, @ToDate)
)
-- select a 1000 random dates
SELECT TOP 1000 caneldarDate
FROM CalendarCTE c
CROSS JOIN Tally t
WHERE t.num < 1000
ORDER BY NEWID()
-- cleanup
DROP TABLE Tally
你用什么版本的SQL Server?我在SQL Server 2012中进行了测试,并在函数中得到'无效的副作用运算符'rand'。“。 – 2012-03-10 10:21:13
谢谢@MikaelEriksson,我已修复查询。问候。 – danihp 2012-08-02 16:15:34