我有一个varchar
列,其中包含042011 MMYYYY格式的数据。我想将其转换为从今天的日期到该列的距离。
我想要一个2.2年或类似的答案。
我尝试过
SELECT datediff(month,FORMAT(GETDATE(),'MM') + FORMAT(GETDATE(),'yyyy'),'042011')
答案 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;