我的例子:
Code FromDate ToDate
-- -------- -------
101 15/12/2012 15/01/2013
101 30/11/2013 20/01/2014
我想计算两个日期之间的差异,今年多少天 ,我怎么能用SQL做到这一点? 结果如下:
Code No.day 2012 2013 2014
-- ------ ---- ---- ----
101 82 17 46 19
答案 0 :(得分:0)
使用此:
SELECT Code,SUM(No.day) AS No.day, SUM(2012) AS 2012, SUM(2013) AS 2013, SUM(2014) AS 2014
FROM TABLENAME GROUP BY Code
根据您当前(编辑)的问题,您应该使用
SELECT DATEDIFF(day,'2012-06-05','2012-08-05') AS Year2012 From TABLENAME
。
例如:
SELECT DATEDIFF(day, '2014/01/01', '2014/04/28');
Result: 117
SELECT DATEDIFF(hour, '2014/04/28 08:00', '2014/04/28 10:45');
Result: 2
SELECT DATEDIFF(minute, '2014/04/28 08:00', '2014/04/28 10:45');
Result: 165
您可以根据自己的要求进行操作。
答案 1 :(得分:0)
尝试类似:
select Code,sum([2012])+sum([2013])+sum([2014]) as 'No.days',sum([2012]),sum([2013]),sum([2014]) from(
select Code,
case when datepart(yy,fromdate)=datepart(yy,todate) and datepart(yy,fromdate)=2012 then datediff(dd,fromdate, todate)
when datepart(yy,fromdate)=2012 and datepart(yy,todate)>2012 then datediff(dd,fromdate,dateadd(yy,1,dateadd(dd,-datepart(dy,DATEADD(yy,1, fromdate)),fromdate)))
when datepart(yy,fromdate)<2012 and datepart(yy,todate)=2012 then DATEPART(dy,todate)
end as '2012',
case when datepart(yy,fromdate)=datepart(yy,todate) and datepart(yy,fromdate)=2013 then datediff(dd,fromdate, todate)
when datepart(yy,fromdate)=2013 and datepart(yy,todate)>2013 then datediff(dd,fromdate,dateadd(yy,1,dateadd(dd,-datepart(dy,DATEADD(yy,1, fromdate)),fromdate)))
when datepart(yy,fromdate)<2013 and datepart(yy,todate)=2013 then DATEPART(dy,todate)
end as '2013',
case when datepart(yy,fromdate)=datepart(yy,todate) and datepart(yy,fromdate)=2014 then datediff(dd,fromdate, todate)
when datepart(yy,fromdate)=2014 and datepart(yy,todate)>2014 then datediff(dd,fromdate,dateadd(yy,1,dateadd(dd,-datepart(dy,DATEADD(yy,1, fromdate)),fromdate)))
when datepart(yy,fromdate)<2014 and datepart(yy,todate)=2014 then DATEPART(dy,todate)
end as '2014'
from myTable
) as daystable
group by Code
如果您需要更多年,则需要在子查询中添加更多字段。
答案 2 :(得分:0)
您需要结合几种不同的技巧,以获得您所追求的结果。
如果您有calendar table,这会有所帮助。这些是非常有用的东西,如果你不熟悉那么值得研究。我的查询假设您没有。在这里,我使用了recursive CTE来动态创建一个。
提示:以我们可以分享的格式提供样本数据,提高您的问题获得答案的几率。
-- Table variables are a good way to share sample data.
DECLARE @Sample TABLE
(
Code INT,
FromDate DATE,
ToDate DATE
)
;
INSERT INTO @Sample
(
Code,
FromDate,
ToDate
)
VALUES
(101, '2012-12-15', '2013-01-15'),
(101, '2013-11-30', '2014-01-20')
;
此查询将源数据连接到日历表。在from和to日期之间每天返回一条记录。使用日历表中的年份列,我们将结果分组。计算记录将返回通过的总天数。要计算年份小计,我们使用conditional aggregation。此技术使用case expression创建新列,这些列根据年份有条件地填充1或0。
/* Returns date counts, split by
* year.
*/
WITH CalendarTable AS
(
/* This CTE returns 1 record for each day
* between Jan 1st 2012 and Dec 31st 2014.
*/
SELECT
CAST('2012-01-01' AS DATE) AS [Date],
2012 AS [Year]
UNION ALL
SELECT
DATEADD(DAY, 1, [Date]) AS [Date],
YEAR(DATEADD(DAY, 1, [Date])) AS [Year]
FROM
CalendarTable
WHERE
[Date] < '2014-12-31'
)
SELECT
s.Code,
COUNT(*) AS [No.Day],
SUM(CASE WHEN ct.[Year] = 2012 THEN 1 ELSE 0 END) AS [2012],
SUM(CASE WHEN ct.[Year] = 2013 THEN 1 ELSE 0 END) AS [2013],
SUM(CASE WHEN ct.[Year] = 2014 THEN 1 ELSE 0 END) AS [2014]
FROM
@Sample AS s
INNER JOIN CalendarTable AS ct ON ct.[Date] >= s.FromDate
AND ct.[Date] < s.ToDate
GROUP BY
s.Code
OPTION
(MAXRECURSION 1096)
;
Code No.day 2012 2013 2014
-- ------ ---- ---- ----
101 82 17 46 19
如果您已有日历表,则可以通过删除CTE并更新连接来简化此查询。
答案 3 :(得分:0)
SELECT code,fromdate,todate,datediff(dd,fromdate,todate),
datediff(dd,case when year(fromdate) < 2012 then '1/1/2012' when year(fromdate) = 2012 then fromdate else '12/31/2012' end,case when year(todate) = 2012 then todate else '12/31/2012'end)'2012',
datediff(dd,case when year(fromdate) < 2013 then '1/1/2013' when year(fromdate) = 2013 then fromdate else '12/31/2013' end,case when year(todate) = 2013 then todate else '12/31/2013'end) '2013',
datediff(dd,case when year(fromdate) < 2014 then '1/1/2014' when year(fromdate) = 2014 then fromdate else '12/31/2014' end,case when year(todate) < 2014 then '1/1/2014' when year(todate) = 2014 then todate else '12/31/2014'end) '2014' FROM (SELECT '101' AS code, datefromparts(2012,12,15) AS fromdate, datefromparts(2013,1,15) AS todate
UNION
SELECT '101' AS code, datefromparts(2013,11,30) AS fromdate, datefromparts(2014,1,20) AS todate
Union
SELECT '101' AS code, datefromparts(2014,11,30) AS fromdate, datefromparts(2016,1,20) AS todate) AS s
希望这会有所帮助