查找用于将财政季度结果与上一年进行比较的查询
Find the query for comparing fiscal quarter results with the previous year
使用 MS SQL Server 2014 和 AdventureWorks2012 数据库。
目前正在尝试制定正确的查询以获得一个结果,该结果显示每个销售人员在同一行的会计季度的总销售额,与上一年的会计季度进行比较。我应该在结果中包含的列是;
- 姓氏
- 销售人员 ID
- 财政年度
- 财政季度
- 财政季度销售额
- 上一财年同一财季的销售额
- 两个时期的收入变化
- 两个时期的收入变化百分比
我的以下查询不包括最后 2 列,因为我不确定如何获取它们?然而,没有它们的查询似乎也不正确,因为它没有得到想要的结果。
我曾尝试 运行 此代码,但 GROUP BY
中没有 soh.OrderDate
,这是我之前为另一个相关查询所做的事情,但是此 returns 出现以下错误因此,我将其重新包含在 GROUP BY
;
中
Column 'Sales.SalesOrderHeader.OrderDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
SELECT pp.LastName, sp.BusinessEntityID AS SalesPersonID,
CASE
WHEN soh.OrderDate BETWEEN '2013-07-01' AND '2014-06-30'
THEN '2013'
END AS FY,
CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN '1'
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN '2'
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN '3'
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN '4'
END AS FQ,
CASE
WHEN soh.OrderDate BETWEEN '2013-07-01' AND '2014-06-30'
THEN
SUM(CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN soh.SubTotal
END)
END AS FQSales,
CASE
WHEN soh.OrderDate BETWEEN '2012-07-01' AND '2013-06-30'
THEN
SUM(CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN soh.SubTotal
END)
END AS SalesSameLastFQ
FROM Sales.SalesPerson sp
INNER JOIN Person.Person pp
ON sp.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh
ON sp.BusinessEntityID = soh.SalesPersonID
GROUP BY pp.LastName, sp.BusinessEntityID, soh.OrderDate;
当前结果,每个销售人员得到不同的排列,但是我希望每个销售人员有 4 个结果,每个 FQ 有 1 个。
LastName SalesPersonID FY FQ FQSales SalesSameLastYr
------------------------------------------------------------------
Alberts 283 NULL 1 NULL NULL
Alberts 283 NULL 1 NULL 32344.342
Alberts 283 NULL 3 NULL NULL
Alberts 283 2013 2 342432 NULL
Alberts 283 NULL 4 NULL 32344.342
Alberts 283 NULL 3 NULL NULL
Alberts 283 NULL 4 NULL 32344.342
Alberts 283 2013 2 436346 NULL
想要的结果:
LastName SalesPersID FY FQ FQSales SalesSameLastYr Change Change%
-----------------------------------------------------------------------
Alberts 283 2013 1 2000 1900 100 5
Alberts 283 2013 2 2200 2000 200 10
Alberts 283 2013 3 2000 2100 -100 -5
Alberts 283 2013 4 3000 2850 150 5
Mathews 291 2013 1 2000 1900 100 5
Mathews 291 2013 2 2200 2000 200 10
Mathews 291 2013 3 2000 2100 -100 -5
Mathews 291 2013 4 3000 2850 150 5
你首先应该将数据分成两个表,一个代表每一年,计算每个表的 FY 和 FQ。:
SELECT pp.LastName, sp.BusinessEntityID AS SalesPersonID,'2013' as FY,
CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN '1'
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN '2'
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN '3'
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN '4'
END AS FQ,
soh.SubTotal
into #tmpCurrentYear
FROM Sales.SalesPerson sp
INNER JOIN Person.Person pp ON sp.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID = soh.SalesPersonID
where soh.OrderDate between '2013-07-01' AND '2014-06-30'
SELECT pp.LastName, sp.BusinessEntityID AS SalesPersonID,'2012' as FY,
CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN '1'
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN '2'
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN '3'
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN '4'
END AS FQ,
soh.SubTotal
into #tmpLastYear
FROM Sales.SalesPerson sp
INNER JOIN Person.Person pp ON sp.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID = soh.SalesPersonID
where soh.OrderDate between '2012-07-01' AND '2013-06-30'
然后加入他们并在没有 orderDate 的情况下进行分组,否则它将为每个日期创建一行:
select t.LastName, t.SalesPersonID,t.FY,t.FQ, sum(t.SubTotal) as FQSales,
sum(ly.SubTotal) as SalesSameLastFQ, sum(t.SubTotal)-sum(ly.SubTotal) as Change,
(sum(t.SubTotal)-sum(ly.SubTotal))/(sum(t.SubTotal)) as ChangePercentage
from #tmpCurrentYear as t
INNER JOIN #tmpLastYear as ly ON t.LastName = ly.LastName and t.BusinessEntityID = ly.BusinessEntityID and t.FQ = ly.FQ
group by t.LastName, t.SalesPersonID,t.FY,t.FQ
使用条件聚合:
SELECT pp.LastName, sp.BusinessEntityID AS SalesPersonID,
v.FY, v.FQ,
SUM(CASE WHEN FY = 2012 THEN soh.SubTotal END) as FY_prev,
SUM(CASE WHEN FY = 2013 THEN soh.SubTotal END) as FY_curr,
( SUM(CASE WHEN FY = 2013 THEN soh.SubTotal END) /
SUM(CASE WHEN FY = 2012 THEN soh.SubTotal END)
) - 1 as percent
FROM Sales.SalesPerson sp INNER JOIN
Person.Person pp
ON sp.BusinessEntityID = pp.BusinessEntityID INNER JOIN
Sales.SalesOrderHeader soh
ON sp.BusinessEntityID = soh.SalesPersonID CROSS APPLY
(VALUES ((CASE WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN '1'
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN '2'
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN '3'
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN '4'
END),
(CASE WHEN MONTH(soh.OrderDate) < 7 THEN YEAR(soh.OrderDate)
ELSE YEAR(soh.OrderDate) + 1
END)
)
) v(FQ, FY)
WHERE FY IN (2013, 2012)
GROUP BY pp.LastName, sp.BusinessEntityID, v.FY, v.FQ;
这使用 CROSS APPLY
来创造价值。这也可以通过 CTE 或子查询来完成。
使用 MS SQL Server 2014 和 AdventureWorks2012 数据库。
目前正在尝试制定正确的查询以获得一个结果,该结果显示每个销售人员在同一行的会计季度的总销售额,与上一年的会计季度进行比较。我应该在结果中包含的列是;
- 姓氏
- 销售人员 ID
- 财政年度
- 财政季度
- 财政季度销售额
- 上一财年同一财季的销售额
- 两个时期的收入变化
- 两个时期的收入变化百分比
我的以下查询不包括最后 2 列,因为我不确定如何获取它们?然而,没有它们的查询似乎也不正确,因为它没有得到想要的结果。
我曾尝试 运行 此代码,但 GROUP BY
中没有 soh.OrderDate
,这是我之前为另一个相关查询所做的事情,但是此 returns 出现以下错误因此,我将其重新包含在 GROUP BY
;
Column 'Sales.SalesOrderHeader.OrderDate' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
SELECT pp.LastName, sp.BusinessEntityID AS SalesPersonID,
CASE
WHEN soh.OrderDate BETWEEN '2013-07-01' AND '2014-06-30'
THEN '2013'
END AS FY,
CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN '1'
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN '2'
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN '3'
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN '4'
END AS FQ,
CASE
WHEN soh.OrderDate BETWEEN '2013-07-01' AND '2014-06-30'
THEN
SUM(CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN soh.SubTotal
END)
END AS FQSales,
CASE
WHEN soh.OrderDate BETWEEN '2012-07-01' AND '2013-06-30'
THEN
SUM(CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN soh.SubTotal
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN soh.SubTotal
END)
END AS SalesSameLastFQ
FROM Sales.SalesPerson sp
INNER JOIN Person.Person pp
ON sp.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh
ON sp.BusinessEntityID = soh.SalesPersonID
GROUP BY pp.LastName, sp.BusinessEntityID, soh.OrderDate;
当前结果,每个销售人员得到不同的排列,但是我希望每个销售人员有 4 个结果,每个 FQ 有 1 个。
LastName SalesPersonID FY FQ FQSales SalesSameLastYr
------------------------------------------------------------------
Alberts 283 NULL 1 NULL NULL
Alberts 283 NULL 1 NULL 32344.342
Alberts 283 NULL 3 NULL NULL
Alberts 283 2013 2 342432 NULL
Alberts 283 NULL 4 NULL 32344.342
Alberts 283 NULL 3 NULL NULL
Alberts 283 NULL 4 NULL 32344.342
Alberts 283 2013 2 436346 NULL
想要的结果:
LastName SalesPersID FY FQ FQSales SalesSameLastYr Change Change%
-----------------------------------------------------------------------
Alberts 283 2013 1 2000 1900 100 5
Alberts 283 2013 2 2200 2000 200 10
Alberts 283 2013 3 2000 2100 -100 -5
Alberts 283 2013 4 3000 2850 150 5
Mathews 291 2013 1 2000 1900 100 5
Mathews 291 2013 2 2200 2000 200 10
Mathews 291 2013 3 2000 2100 -100 -5
Mathews 291 2013 4 3000 2850 150 5
你首先应该将数据分成两个表,一个代表每一年,计算每个表的 FY 和 FQ。:
SELECT pp.LastName, sp.BusinessEntityID AS SalesPersonID,'2013' as FY,
CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN '1'
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN '2'
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN '3'
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN '4'
END AS FQ,
soh.SubTotal
into #tmpCurrentYear
FROM Sales.SalesPerson sp
INNER JOIN Person.Person pp ON sp.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID = soh.SalesPersonID
where soh.OrderDate between '2013-07-01' AND '2014-06-30'
SELECT pp.LastName, sp.BusinessEntityID AS SalesPersonID,'2012' as FY,
CASE
WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN '1'
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN '2'
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN '3'
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN '4'
END AS FQ,
soh.SubTotal
into #tmpLastYear
FROM Sales.SalesPerson sp
INNER JOIN Person.Person pp ON sp.BusinessEntityID = pp.BusinessEntityID
INNER JOIN Sales.SalesOrderHeader soh ON sp.BusinessEntityID = soh.SalesPersonID
where soh.OrderDate between '2012-07-01' AND '2013-06-30'
然后加入他们并在没有 orderDate 的情况下进行分组,否则它将为每个日期创建一行:
select t.LastName, t.SalesPersonID,t.FY,t.FQ, sum(t.SubTotal) as FQSales,
sum(ly.SubTotal) as SalesSameLastFQ, sum(t.SubTotal)-sum(ly.SubTotal) as Change,
(sum(t.SubTotal)-sum(ly.SubTotal))/(sum(t.SubTotal)) as ChangePercentage
from #tmpCurrentYear as t
INNER JOIN #tmpLastYear as ly ON t.LastName = ly.LastName and t.BusinessEntityID = ly.BusinessEntityID and t.FQ = ly.FQ
group by t.LastName, t.SalesPersonID,t.FY,t.FQ
使用条件聚合:
SELECT pp.LastName, sp.BusinessEntityID AS SalesPersonID,
v.FY, v.FQ,
SUM(CASE WHEN FY = 2012 THEN soh.SubTotal END) as FY_prev,
SUM(CASE WHEN FY = 2013 THEN soh.SubTotal END) as FY_curr,
( SUM(CASE WHEN FY = 2013 THEN soh.SubTotal END) /
SUM(CASE WHEN FY = 2012 THEN soh.SubTotal END)
) - 1 as percent
FROM Sales.SalesPerson sp INNER JOIN
Person.Person pp
ON sp.BusinessEntityID = pp.BusinessEntityID INNER JOIN
Sales.SalesOrderHeader soh
ON sp.BusinessEntityID = soh.SalesPersonID CROSS APPLY
(VALUES ((CASE WHEN MONTH(soh.OrderDate) BETWEEN 7 AND 9 THEN '1'
WHEN MONTH(soh.OrderDate) BETWEEN 10 AND 12 THEN '2'
WHEN MONTH(soh.OrderDate) BETWEEN 1 AND 3 THEN '3'
WHEN MONTH(soh.OrderDate) BETWEEN 4 AND 6 THEN '4'
END),
(CASE WHEN MONTH(soh.OrderDate) < 7 THEN YEAR(soh.OrderDate)
ELSE YEAR(soh.OrderDate) + 1
END)
)
) v(FQ, FY)
WHERE FY IN (2013, 2012)
GROUP BY pp.LastName, sp.BusinessEntityID, v.FY, v.FQ;
这使用 CROSS APPLY
来创造价值。这也可以通过 CTE 或子查询来完成。