【问题标题】:How to convert MMYYYY (042011) to date and find datediff for todays date如何将 MMYYYY (042011) 转换为日期并找到今天日期的 datediff
【发布时间】:2019-06-06 17:28:20
【问题描述】:

我有一个 varchar 列,其中包含 042011 MMYYYY 格式的数据。我想将其转换为从今天的日期到该列的差距。

我想要一个像 2.2 年或相关的答案。

我试过了

SELECT datediff(month,FORMAT(GETDATE(),'MM') + FORMAT(GETDATE(),'yyyy'),'042011')

【问题讨论】:

  • 请改进你的问题。您尝试过的 SQL 代码在哪里?
  • 如果您使用 yyyymmdd,您将始终获得更一致的结果,适用于世界任何地方
  • @Sharan MMYYYY 不是日期。没有月日就不可能有日期。为什么需要它?
  • @sharan 你想做什么?在问题中解释您的实际问题,而不是您认为如何解决。如果您想计算每月或任何其他时期的聚合,使用日历表会更容易很多,即一个包含 20-50 年日期的表,其中包含年、月、月日、周数、业务报告期等。每月的汇总变成一个简单的GROUP BY Year, Month。逐月、逐年、逐年等成为“年”或“月”列上的简单联接和过滤器
  • @sharan 这些额外字段之一可以轻松成为您可以用于加入的MMYYYY 字符串。这样您就不必解析任何内容,只需加入该列上的日历表并执行您想要的任何聚合

标签: sql sql-server tsql


【解决方案1】:

MMYYYY 不是日期,因为它不包含月份。我怀疑这是一个指向特定报告期的字符串。

处理此类时间段的典型方法是使用Calendar table,例如 20 年或 50 年的日期,以及年、月、月中的某天、周数、月份名称以及最重要的业务报告的额外字段期间。

此表使每个时期的聚合或比较不同时期变得更加容易和快捷。在各个列上添加索引,以便基于年份等进行非常快速的连接和分组。

假设日历表看起来有点像这样:

create table Calendar
(
    Date DATE NOT NULL PRIMARY KEY,
    Year int NOT NULL
    Month int not null,
    ....
    MonthLabel char(6),
    IX_Calendar_Year (Year),
    ....
    IX_Calendar_MonthLabel (MonthLabel),
)

您可以计算例如每月的总和:

select Year,Month,SUM(Total) as Total
From Orders inner join Calendar 
    on Calendar.Date=Orders.Date
group by Year, Month

使用报告期同样简单:

select MonthLabel,SUM(Total) as Total
From Orders inner join Calendar 
    on Calendar.Date=Orders.Date
group by MonthLabel

如果源数据包含报告期标签,您可以加入该列:

select MonthLabel,SUM(Total) as Total
From Orders inner join Calendar 
    on Calendar.MonthLabel=Orders.MonthLabel

如果标签来自 UI,例如报告工具:

select Year,Month,SUM(Total) as Total
From Orders inner join Calendar 
    on Calendar.Date=Orders.Date
WHERE MonthLabel=@thatLabel
group by Year, Month

所有这些查询都快速,因为它们不涉及解析,并且连接、分组、过滤操作使用索引列

【讨论】:

    【解决方案2】:

    你想要这样的东西吗?

    SELECT ROUND(CAST(DATEDIFF (month,CAST(RIGHT ('042011',4) + '-' + LEFT ('042011',2) + '-' + '01' AS DATE),CAST(GETDATE () AS DATE)) AS FLOAT) / CAST(12 AS FLOAT),2)
    

    结果:8.2

    我将您的 varchar 列设置为 dateformat (2011-04-01) 我添加了一个默认日期 (1),然后将其月份 timediff 设置为 currentdate 并将月份除以 12 以获得年数。还进行了一些浮点转换和四舍五入以获得所需的结果。

    【讨论】:

    • 很高兴我能帮上忙。 :)
    • @sharan 你用 012011 测试过这个查询吗?我的意思是通过不同的月份?
    • @sharan 请用从 1 到 12 的月份进行测试,并检查这是否真的是你想要的?这确实返回的结果与我认为您的问题不同
    • @GuidoG 不,你可以自己试试。你可以试试062019。
    • 022011 和 032011 例如都返回相同的差异
    【解决方案3】:
    SELECT DATEDIFF(
        month, 
        GETDATE(), 
        PARSE(
            CONCAT(
                RIGHT('042011', 4),'-',LEFT('042011', 2)) as date USING 'en-US'))
    

    输出

    -98
    

    表示 98 个月前

    【讨论】:

      【解决方案4】:

      我知道代码很乱。但是你可以为它写一个函数。

      试试这个:

      SELECT cast(datediff(year,CONVERT(DATETIME,'20110301',103),CONVERT(DATETIME,(FORMAT(GETDATE(),'yyyyMM')+'01'),103)) as varchar)+'.'+
      cast((datediff(month,CONVERT(DATETIME,'20110301',103),CONVERT(DATETIME,(FORMAT(GETDATE(),'yyyyMM')+'01'),103)) -(datediff(year,CONVERT(DATETIME,'20110301',103),CONVERT(DATETIME,(FORMAT(GETDATE(),'yyyyMM')+'01'),103))*12)) as varchar)
      

      或者

      如果你想通过函数来​​实现,body 会是这样的:

      Declare @currentdate;
      Declare @datetocompare varchar(10);
      Declare @years varchar(10);
      Declare @months varchar(10);
      
      set @datetocompare='20110401';
      
      set @currentdate=GETDATE();
      
      select @years=datediff(year,CONVERT(DATETIME,@datetocompare,103),@currentdate);
      
      select @months=datediff(month,CONVERT(DATETIME,@datetocompare,103),@currentdate)-(datediff(year,CONVERT(DATETIME,@datetocompare,103),@currentdate)*12);
      
      select @years  +'.' +@months +' Years' asYearMonthDay;
      

      【讨论】:

        【解决方案5】:

        让我们一步一步构建这个,这样你就可以遵循逻辑

        declare @value varchar(6) = '042011'
        declare @datestring varchar(8)
        declare @date date
        
        -- convert your format to a regional independant format including day 1
        select @datestring = concat(right(@value, 4), left(@value, 2), '01')
        
        -- convert this into a valid date type
        select @date = convert(date, @datestring)
        
        -- now we can get the difference, first the years and then the months
        select  datediff(month, @date, getdate()) / 12 as years,
                datediff(month, @date, getdate()) % 12 as months
        

        整体看起来像这样

        select datediff(month, convert(date, (concat(right(@value, 4), left(@value, 2), '01'))), getdate()) / 12 as years,
               datediff(month, convert(date, (concat(right(@value, 4), left(@value, 2), '01'))), getdate()) % 12 as months
        

        @value 可以被表中的列替换

        例如它在查询中的样子

        declare @table table (value varchar(8))
        insert into @table (value) 
        values ('012011'), ('022011'), ('032011'), ('042011'), ('052011'), ('062011'), ('072011'), ('082011'), ('092011'), ('102011'), ('112011'), ('122011')
        
        select value,
               datediff(month, convert(date, (concat(right(value, 4), left(value, 2), '01'))), getdate()) / 12 as years,
               datediff(month, convert(date, (concat(right(value, 4), left(value, 2), '01'))), getdate()) % 12 as months
        from   @table
        

        结果是(getdate() returned 20190604 on the time of writing this)

        value   years   months  
        -----   -----   ------  
        012011  8        5  
        022011  8        4  
        032011  8        3  
        042011  8        2  
        052011  8        1  
        062011  8        0  
        072011  7       11  
        082011  7       10  
        092011  7        9  
        102011  7        8  
        112011  7        7  
        122011  7        6  
        

        【讨论】:

          【解决方案6】:

          一种可能的方法是下一个语句。

          输入:

          CREATE TABLE #Dates (
              MmYyyy varchar(6)
          )
          INSERT INTO #Dates 
              (Mmyyyy)
          VALUES
              ('042011'),
              ('052011'),
              ('062011')
          

          T-SQL:

          SELECT CONCAT(
              DATEDIFF(month,TRY_CONVERT(date, CONCAT(RIGHT(MmYyyy, 4), LEFT(MmYyyy, 2), '01')), GETDATE()) / 12, 
              ' y, ',
              DATEDIFF(month,TRY_CONVERT(date, CONCAT(RIGHT(MmYyyy, 4), LEFT(MmYyyy, 2), '01')), GETDATE()) % 12,
              ' m'
          ) AS [Difference]
          FROM #Dates
          

          输出:

          Difference
          8 y, 2 m
          8 y, 1 m
          8 y, 0 m
          

          注意事项:

          关于在你的问题中“我想要一个像 2.2 年或相关的答案”。如果你想要正确的结果,计算应该是years and months,而不是years and months / 12。请看下一个示例脚本 - 3 个月和 4 个月以及 9 个月和 10 个月的差异相同。四舍五入到小数点后一位以上会使结果难以理解。

          SELECT CONVERT(numeric(10, 1), v.Nmr / 12.0) AS [Difference]
          FROM (VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12)) v(Nmr)
          
          Difference
          0.1
          0.2
          0.3
          0.3
          0.4
          0.5
          0.6
          0.7
          0.8
          0.8
          0.9
          1.0
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-11-13
            • 2018-01-31
            • 1970-01-01
            • 2016-12-16
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-08-03
            相关资源
            最近更新 更多