我是新來的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