![](/img/trans.png)
[英]SQL Server: determining the Years, Months, Weeks and Days between two dates
[英]SQL Show Number of Months and Years Between Two Dates
我有一张表,显示产品的开始日期和结束日期。 我在表中有总价值和产品名称。 我希望能够显示两个日期之间的月份和年份,同时包括产品名称和该时间段内的平均值。 我一直在尝试使用一个查询来解决单个产品的问题。 我需要将结果显示在多个产品上。 我收到一条错误消息,说我不能在子查询中查询多个项目。 是否可以得到我想要的结果? 谢谢您的帮助。 非常感谢。
产品数据示例
Product Value Start Date End Date
Widget A 100 1/1/2012 5/1/2013
Widget B 500 2/1/2010 6/1/2012
所需结果
Product Date Month Year Value
Widget A 1/1/2012 Jan 2012 5.88
Widget A 2/1/2012 Feb 2012 5.88
Widget A 3/1/2012 Mar 2012 5.88
Widget A 4/1/2012 Apr 2012 5.88
Widget A 5/1/2012 May 2012 5.88
Widget A 6/1/2012 Jun 2012 5.88
Widget A 7/1/2012 Jul 2012 5.88
Widget A 8/1/2012 Aug 2012 5.88
Widget A 9/1/2012 Sep 2012 5.88
Widget A 10/1/2012 Oct 2012 5.88
Widget A 11/1/2012 Nov 2012 5.88
Widget A 12/1/2012 Dec 2012 5.88
Widget A 1/1/2013 Jan 2013 5.88
Widget A 2/1/2013 Feb 2013 5.88
Widget A 3/1/2013 Mar 2013 5.88
Widget A 4/1/2013 Apr 2013 5.88
Widget A 5/1/2013 May 2013 5.88
Widget B 2/1/2010 Feb 2010 17.24
Widget B 3/1/2010 Mar 2010 17.24
Widget B 4/1/2010 Apr 2010 17.24
Widget B 5/1/2010 May 2010 17.24
Widget B 6/1/2010 Jun 2010 17.24
Widget B 7/1/2010 Jul 2010 17.24
Widget B 8/1/2010 Aug 2010 17.24
Widget B 9/1/2010 Sep 2010 17.24
Widget B 10/1/2010 Oct 2010 17.24
Widget B 11/1/2010 Nov 2010 17.24
Widget B 12/1/2010 Dec 2010 17.24
Widget B 1/1/2011 Jan 2011 17.24
Widget B 2/1/2011 Feb 2011 17.24
Widget B 3/1/2011 Mar 2011 17.24
Widget B 4/1/2011 Apr 2011 17.24
Widget B 5/1/2011 May 2011 17.24
Widget B 6/1/2011 Jun 2011 17.24
Widget B 7/1/2011 Jul 2011 17.24
Widget B 8/1/2011 Aug 2011 17.24
Widget B 9/1/2011 Sep 2011 17.24
Widget B 10/1/2011 Oct 2011 17.24
Widget B 11/1/2011 Nov 2011 17.24
Widget B 12/1/2011 Dec 2011 17.24
Widget B 1/1/2012 Jan 2012 17.24
Widget B 2/1/2012 Feb 2012 17.24
Widget B 3/1/2012 Mar 2012 17.24
Widget B 4/1/2012 Apr 2012 17.24
Widget B 5/1/2012 May 2012 17.24
Widget B 6/1/2012 Jun 2012 17.24
您需要交叉连接到数字/日期表。
如果您没有,则使用系统表和ROW_NUMBER()
即时创建它们相对便宜。
WITH Product AS
( SELECT Product,
Value = CAST(Value AS DECIMAL(10, 2)),
StartDate = CAST(StartDate AS DATE),
EndDate = CAST(EndDate AS DATE)
FROM (VALUES
('Widget A', 100, '20120101', '20130501'),
('Widget b', 500, '20100201', '20120601')
) t (Product, Value, StartDate, EndDate)
), Numbers AS
( SELECT Number = ROW_NUMBER() OVER(ORDER BY a.object_id) - 1
FROM sys.all_objects a
)
SELECT p.Product,
d.[Date],
MonthYear = LEFT(DATENAME(MONTH, d.[Date]), 3) + ' ' + DATENAME(YEAR, d.[Date]),
Value = CAST(p.Value / (1 + DATEDIFF(MONTH, p.StartDate, p.EndDate)) AS DECIMAL(5, 2))
FROM Product p
CROSS JOIN Numbers n
OUTER APPLY (SELECT Date = DATEADD(MONTH, n.Number, p.StartDate)) d
WHERE d.[Date] <= p.EndDate
ORDER BY p.Product, [Date];
有关静态和即时生成和使用数字/日期表的更多信息,请阅读以下系列:
第一步,获取日期列表。 输出中的每月日期必须来自某处 ...这就是SQL的工作方式。 创建和维护“日历表”非常普遍,但是还有其他方法。
CREATE TABLE months ([Date] date)
--Populate table with a list of first-of-months
SELECT
p.[Product],
m.[Date],
LEFT(DATENAME(month,m.[Date]),3) AS [Month]
YEAR(m.[Date]) AS [Year]
p.[Value]/(DATEDIFF(month,p.[Start Date],p.[End Date])+1) AS [Value]
FROM months m
INNER JOIN products p ON (m.[Date] BETWEEN p.[Start Date] AND p.[End Date])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.