我的数据库中有一个临时表,包含费率和期限:
Rate | Period
-----+--------
3 | Week
1 | Month
2 | Month
1 | Week
3 | Year
1 | Monh
1 | Month
1 | Month
1 | Month
1 | Month
1 | Month
6 | Year
2 | Month
我需要生成2014年的随机日期。例如,'6 Year'应该是2014年的6个随机日期。 1周应该是2014年每周的随机日期。愿有人帮帮我吗?
所以,这是我的功能。但日期几乎不正确。也许有人可能会发现错误?
CREATE FUNCTION GenerateDate(@date_from date, @Rate int, @Period nvarchar(50))
RETURNS @LIST TABLE(item date)
BEGIN
DECLARE @i int, @j int, @d int
DECLARE @date date
IF (@Period LIKE 'Y%')
BEGIN
SET @i=0
WHILE (@i < @Rate)
BEGIN
SET @date = DATEADD (day, dbo.Amount(0,364), @date_from)
IF @date NOT IN (SELECT * FROM @LIST)
BEGIN
INSERT INTO @LIST VALUES (@date)
SET @i=@i+1
END
END
END
IF (@Period LIKE 'M%')
BEGIN
SET @i=1
WHILE (@i <= 12)
BEGIN
SET @j=0
SET @d = CASE @i
WHEN 2 THEN 28
WHEN 4 THEN 30
WHEN 6 THEN 30
WHEN 9 THEN 30
WHEN 11 THEN 30
ELSE 31
END
WHILE (@j < @Rate)
BEGIN
SET @date = DATEADD (day, dbo.Amount(0,@d-1), @date_from)
IF @date NOT IN (SELECT * FROM @LIST)
BEGIN
INSERT INTO @LIST VALUES (@date)
SET @j=@j+1
END
END
SET @date_from = DATEADD (month, 1, @date_from)
SET @i=@i+1
END
END
IF (@Period LIKE 'W%')
BEGIN
SET @i = 1
WHILE (@i <= 52)
BEGIN
SET @j=0
WHILE (@j < @Rate)
BEGIN
SET @date = DATEADD (day, dbo.Amount(0,6), @date_from)
IF @date NOT IN (SELECT * FROM @LIST)
BEGIN
INSERT INTO @LIST VALUES (@date)
SET @j=@j+1
END
END
SET @date_from = DATEADD (week, 1, @date_from)
SET @i=@i+1
END
END
RETURN
END
CREATE FUNCTION Amount(@AmountMin float, @AmountMax float)
RETURNS float
AS
BEGIN
DECLARE @Amount float = (SELECT new_rand FROM RandomNumbers)*(@AmountMax-@AmountMin) + @AmountMin
RETURN @Amount
END
GO
CREATE VIEW RandomNumbers
AS
SELECT cast( RAND(CHECKSUM(NEWID()))*1000 AS INT) AS new_rand
GO
答案 0 :(得分:1)
要获得2014年的6个不同日期,您可以尝试以下内容 -
DECLARE @Counter INT
DECLARE @MaxDateInterval INT
DECLARE @TmpDate DATE
DECLARE @NoOfDate INT
DECLARE @ResultDatesForYr TABLE (TmpDate DATE)
SET @Counter = 0
SET @NoOfDate = 6
SET @TmpDate = '2014-01-01'
SET @MaxDateInterval = FLOOR((365 - @NoOfDate)/@NoOfDate)
WHILE (@Counter < @NoOfDate)
BEGIN
SELECT @TmpDate = DATEADD(DAY, (SELECT (1+FLOOR(@MaxDateInterval*RAND()))), @TmpDate)
INSERT INTO @ResultDatesForYr(TmpDate) VALUES (@TmpDate)
SET @Counter = @Counter+1
END
SELECT * FROM @ResultDatesForYr
您可以编写一个不接受所需日期和年份
的函数答案 1 :(得分:1)
使用日历表的概念证明!
DECLARE @year int = 2014
, @rate int = 3
, @period char(5) = 'Month'
; WITH this_year AS (
SELECT the_date
, CASE @period
WHEN 'Year' THEN DatePart(year , the_date)
WHEN 'Month' THEN DatePart(month , the_date)
WHEN 'Week' THEN DatePart(iso_week, the_date)
WHEN 'Day' THEN DatePart(day , the_date)
END As groups
, NewID() As random
FROM dbo.calendar
WHERE DatePart(year, the_date) = @year
)
, x AS (
SELECT the_date
, Row_Number() OVER (PARTITION BY groups ORDER BY random) As sequence
FROM this_year
)
SELECT the_date
FROM x
WHERE sequence <= @rate
;
您可以了解如何在网络上构建日历表。 Here's one I made earlier
改进了加入表格的代码......
DECLARE @t table (
rate int
, period char(5)
, UNIQUE (period, rate)
);
INSERT INTO @t (rate, period)
VALUES (3, 'Year' ) -- 3
, (2, 'Month') -- 24
, (1, 'Week' ) -- 52 (or 53, depending on the year)
-- = 79 (or 80)
;
; WITH this_year AS (
SELECT calendar.the_date
, t.rate
, t.period
, CASE t.period
WHEN 'Year' THEN DatePart(year , the_date)
WHEN 'Month' THEN DatePart(month , the_date)
WHEN 'Week' THEN DatePart(iso_week, the_date)
WHEN 'Day' THEN DatePart(day , the_date)
END As groups
, NewID() As random
FROM dbo.calendar
CROSS
JOIN @t As t
WHERE DatePart(year, calendar.the_date) = Year(Current_Timestamp)
)
, x AS (
SELECT the_date
, rate
, period
, groups
, Row_Number() OVER (PARTITION BY period, rate, groups ORDER BY random) As sequence
FROM this_year
)
SELECT *
FROM x
WHERE sequence <= rate
;
答案 2 :(得分:0)
让我们努力获得一周的随机日期: 首先,我们得到我们拍摄的时间长度
DATEDIFF(MINUTE, 0, DATEADD(WEEK, 1, 0))
这将返回10080作为一周内的最大分钟数。
此代码从现在开始在一周范围内获得随机分钟。
SELECT DATEADD(MINUTE, RAND() * 10080, GETDATE())
您可以轻松地将其更改为使用天数,但我认为日期时间会更有趣。
答案 3 :(得分:-1)
例如,如果您想在2009-12-25和2009-12-28之间生成随机日期,请编写
选择'2009-12-25'+ interval rand()* 3天
对我来说,我想要一个2008年到2009年之间的价值(一年:60秒* 60分钟* 24小时* 365天= 31536000)。因为Unix时间戳不支持分数,所以需要将值四舍五入为int。 (价值的下限或四舍五入)。
SELECT FROM_UNIXTIME(
UNIX_TIMESTAMP('2008-01-01 01:00:00')+FLOOR(RAND()*31536000)
);