生成一段时间的随机日期

时间:2015-03-16 12:28:23

标签: sql sql-server

我的数据库中有一个临时表,包含费率和期限:

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

4 个答案:

答案 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)
);