我有一个表格,显示产品的开始日期和结束日期。我在表格中有总价值和产品名称。我希望能够显示两个日期之间的月份和年份,同时包括产品名称和该时间段内的平均值。我一直在尝试使用一个解决单个产品问题的查询。我需要在多个产品中显示结果。我收到一条错误消息,说我无法查询子查询中的多个项目。有可能得到我正在寻找的结果吗?谢谢您的帮助。非常感谢。
SQL to display both month and year 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
答案 0 :(得分:1)
您需要交叉加入数字/日期表。
如果你没有,那么使用系统表和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];
<强> Example on SQL Fiddle 强>
关于生成和使用数字/日期表的一些进一步阅读,无论是静态还是动态,请看一下这个系列:
答案 1 :(得分:0)
第一步,获取日期列表。输出中的每月日期必须来自某个地方 ...这就是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])