如何将MMYYYY(042011)转换为日期并查找当日日期的datediff

时间:2019-06-04 06:50:09

标签: sql sql-server tsql

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

我想要一个2.2年或类似的答案。

我尝试过

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

6 个答案:

答案 0 :(得分:2)

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

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

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

假设Calendar表看起来像这样:

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

如果标签来自用户界面,例如报告工具:

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

所有这些查询都是 fast ,因为它们不涉及解析,并且联接,分组,过滤操作均使用索引列

答案 1 :(得分:1)

您想要这样的东西吗?

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以获取年数。还进行了一些浮点运算和舍入以获得所需的结果。

答案 2 :(得分:0)

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

输入:

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个月之间存在相同的差异。舍入到小数点后1位以上会使resul难以理解。

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

答案 3 :(得分:0)

SELECT DATEDIFF(
    month, 
    GETDATE(), 
    PARSE(
        CONCAT(
            RIGHT('042011', 4),'-',LEFT('042011', 2)) as date USING 'en-US'))

输出

-98

意味着98个月前

答案 4 :(得分:0)

让我们逐步构建此步骤,以便您可以遵循逻辑

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  

答案 5 :(得分:0)

我知道代码很乱。但是您可以为其编写函数。

尝试一下:

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)

如果您想通过功能来做到这一点,身体将看起来像这样:

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;