【问题标题】:Generate a day date according to existing month+year+daydiff根据已有的月+年+日差异生成一天日期
【发布时间】:2013-08-01 07:43:35
【问题描述】:

我使用的是 SQL Server 2008。

我有一张包含这 5 列的表格:

StartMonth, StartYear, EndMonth, EndYear, DaysBetween

我没有这些日期中的哪一天,这就是我想要生成的。

例如:

12     2008  1  2009         8

我想创建一个 random 日期(开始日期和结束日期,格式为 dd/mm/yyyy),其中将包含 day 并将在我在天之间

拥有的数据

例如,如果我知道我有 8 天 (DaysBetween) 并且 startmonth 是 12,那么日期必须是 从 2008 年 12 月 24 日起,如果我加上 8 天,我会得到 EndMonth (1/2009)

如果我选择 2/12/2008 日期,我会得到 10/12/2008,这不好,因为该月仍然是 12.... 我需要 1 (2009)

如何生成有效日期?

【问题讨论】:

  • 抱歉,请问您的输入参数是什么?
  • 生成随机日期的目的是什么?

标签: sql sql-server sql-server-2008


【解决方案1】:

这样的?

WITH N(n) AS (
    SELECT a*6+b FROM
    (VALUES(0),(1),(2),(3),(4),(5))a(a),
    (VALUES(1),(2),(3),(4),(5),(6))b(b)
), T(StartMonth,StartYear,EndMonth,EndYear,DaysBetween) AS (
    SELECT 12, 2008, 1, 2009, 8
)

SELECT *
FROM (
    SELECT *, DATEADD (dd, -n, DATEADD (mm, StartMonth, DATEADD (yy, StartYear - 1900, '19000101'))) AS dt
    FROM T
    INNER JOIN N ON DaysBetween >= n
) T
WHERE MONTH (dt) = StartMonth
    AND YEAR (dt) = StartYear
    AND MONTH (DATEADD (dd, DaysBetween, dt)) = EndMonth
    AND YEAR (DATEADD (dd, DaysBetween, dt)) = EndYear

【讨论】:

  • 看起来非常好,我需要根据我的数据对其进行调整...非常感谢。顺便说一句...我执行了您的查询,我得到了 8 行和 8 个可能的日期...我只需要 1 个随机日期而不是 8...我需要更改什么才能获得 1 行?
  • @AviShain 添加 SELECT TOP 1 ... 和 .. ORDER BY NEWID() 以获得 1 个随机行
【解决方案2】:

这是一个示例:

WITH CTE_Start AS 
(
   SELECT DATEADD(dd,-(ABS(CHECKSUM(NewId())) % DaysBetween+1),dateadd(mm, (EndYear - 1900) * 12 + EndMonth - 1,0)) StartDate, DaysBetween
   FROM dbo.This5Columns
)
SELECT StartDate, DATEADD(dd,DaysBetween,StartDate) AS EndDate
FROM CTE_Start

ABS(CHECKSUM(NewId())) % DaysBetween+1 用于获取 1 到 DaysBetween 之间的随机天数,

dateadd(mm, (EndYear - 1900) * 12 + EndMonth - 1,0) 获取结束月份的第一个日期(可能的最早结束日期)

然后将两者相减得到 StartDate,然后再次添加 DaysBetween 得到 EndDate

SQLFiddle DEMO

【讨论】:

    【解决方案3】:

    你需要解决这个问题:

    1. 在 1 和 DaysBetween 之间创建一个随机值
    2. 使用 DateAdd 函数选择下个月第一天前 X 天的日期(X 是前一部分的值)。

    要创建随机值,请尝试以下操作:

    SELECT Cast((  DAYSBETWEEN   ) * Rand(Cast(Newid() AS VARBINARY)) + 1 
                AS 
                       TINYINT) AS 'randomNumber' 
    FROM   TABLE 
    

    然后添加dateadd函数:

    SELECT Dateadd(DD, Cast(( DAYSBETWEEN  ) * Rand(Cast(Newid() AS 
                                                                    VARBINARY)) 
                                   + 1 AS 
                                               TINYINT), Dateadd(MONTH, 1, 
                                                         Cast( 
                  Cast(STARTMONT AS VARCHAR(2)) + '-01-' 
                  + Cast(@StartYear AS VARCHAR(4)) AS DATE))) 
    FROM   TABLE 
    

    【讨论】:

    • 同时使用RANDNEWID() 不是多余的吗? RAND() 一个人也会这样做。还有DAYSBETWEEN + 1 - 1?整个第一个表达式可能只是SELECT CAST(DAYSBETWEEN * Rand() + 1 AS TINYINT)
    • RAND() 单独在查询中不起作用!它将为所有行返回一个随机值。 NEWID 有助于为每一行重新设定 RAND 函数。
    • 哦,是的。好想法!我知道我不使用 RAND 是有原因的,但我想不出来 :)
    猜你喜欢
    • 2018-04-24
    • 2016-07-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    • 1970-01-01
    相关资源
    最近更新 更多