2015-03-16 3 views
1

У меня есть временная таблица в моей базе данных с тарифами периода:Сформировать произвольную дату в течение некоторого периода

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» должно быть 6 случайных дат для 2014 года. 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 @[email protected]+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 @[email protected]+1 
      END 
     END 
     SET @date_from = DATEADD (month, 1, @date_from) 
     SET @[email protected]+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 @[email protected]+1 
      END 
     END 
     SET @date_from = DATEADD (week, 1, @date_from) 
     SET @[email protected]+1 
    END 
END 
RETURN 
END 

CREATE FUNCTION Amount(@AmountMin float, @AmountMax float) 
RETURNS float 
AS 
    BEGIN 
     DECLARE @Amount float = (SELECT new_rand FROM RandomNumbers)*(@[email protected]) + @AmountMin 
     RETURN @Amount 
    END 
GO 

CREATE VIEW RandomNumbers 
AS 
SELECT cast(RAND(CHECKSUM(NEWID()))*1000 AS INT) AS new_rand 
GO 
+2

вы ли попробовать что-нибудь самостоятельно? Если вы не знаете, как это сделать, я бы предложил нанять подрядчика, чтобы сделать это ... –

+0

«1 неделя должна быть случайной датой для каждой недели в 2014 году» - может ли она быть 1-й датой каждой недели или она должна быть случайный? – Kartic

+0

Картику, это должно быть случайным. –

ответ

-1

Например, если вы хотите, чтобы сгенерировать случайную дату между 2009-12-25 и 2009-12-28 Вы пишете

выберите '2009-12-25' + интервал рандов() * 3 день

Для меня я хотел иметь значение между 2008 и 2009 годами (один год: 60 секунд * 60 минут * 24 часа * 365 дней = 31536000). Поскольку временная метка Unix не поддерживает фракции, вам необходимо округлить значение до int. (поместите или округлите значение).

SELECT FROM_UNIXTIME(
UNIX_TIMESTAMP('2008-01-01 01:00:00')+FLOOR(RAND()*31536000) 
); 
+0

Этот вопрос не имеет ничего общего с UNIX. –

+0

Вы понимаете, что это sql-сервер? –

+0

К сожалению, вы правы. –

0

Позволяет работать на получение произвольную дату на неделю: Сначала мы получим отрезок времени мы снимаем для

DATEDIFF(MINUTE, 0, DATEADD(WEEK, 1, 0)) 

Это возвращает 10080 как максимальное число минут в неделю.

Этот код получает случайную минуту в пределах недельного диапазона, начиная с этого момента.

SELECT DATEADD(MINUTE, RAND() * 10080, GETDATE()) 

Вы можете легко изменить это, чтобы использовать дни, вместо этого, но я думал, что datetime будет более интересным для примера.

+0

почему нисходящий? –

+0

Не знаю, почему -1. Я попытаюсь проверить ваш код. Спасибо –

+0

Спасибо! Теперь я попытаюсь написать функцию, которая будет принимать «курс» и «период»! –

1

Чтобы получить 6 различных дат в 2014 году, вы можете попробовать что-то вроде ниже -

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

Доказательство концепции с использованием календарь таблицы!

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 
; 
Смежные вопросы