Oracle 比如说,如果我们在2012年上个季度没有销售,那么在我的相关输出中显示空值。您的查询将连接到上一个平均值,我不希望:(我已经添加了第二个示例,展示了如何使用分区外部联接加密数据,以便获得所需的GAP担心我的要求随着时间的变化而变化,现在我也有了一个区域栏,
Oracle 比如说,如果我们在2012年上个季度没有销售,那么在我的相关输出中显示空值。您的查询将连接到上一个平均值,我不希望:(我已经添加了第二个示例,展示了如何使用分区外部联接加密数据,以便获得所需的GAP担心我的要求随着时间的变化而变化,现在我也有了一个区域栏,,oracle,common-table-expression,window-functions,analytic-functions,Oracle,Common Table Expression,Window Functions,Analytic Functions,比如说,如果我们在2012年上个季度没有销售,那么在我的相关输出中显示空值。您的查询将连接到上一个平均值,我不希望:(我已经添加了第二个示例,展示了如何使用分区外部联接加密数据,以便获得所需的GAP担心我的要求随着时间的变化而变化,现在我也有了一个区域栏,现在我必须根据每个区域、每个产品、每年和每个季度进行分区。在此之前,我计算了simple avg现在完全不同了。因此,我尝试通过您的示例在分区中添加区域和产品qtr,但对于上一季度没有销售的某些产品,它在上一季度的销售栏中显示其他产品的avg销
比如说,如果我们在2012年上个季度没有销售,那么在我的相关输出中显示空值。您的查询将连接到上一个平均值,我不希望:(我已经添加了第二个示例,展示了如何使用分区外部联接加密数据,以便获得所需的GAP担心我的要求随着时间的变化而变化,现在我也有了一个区域栏,现在我必须根据每个区域、每个产品、每年和每个季度进行分区。在此之前,我计算了simple avg现在完全不同了。因此,我尝试通过您的示例在分区中添加区域和产品qtr,但对于上一季度没有销售的某些产品,它在上一季度的销售栏中显示其他产品的avg销售。还有一件事,如果本季度没有销售,它应该是上一季度的avg销售。我一直计算到最后一个条件关于如何计算销售,如果销售不在当前季度,我没有得到它。我正在添加我的代码,如果你能帮助我你的查询工作正确,但它是沉重的,所以我们可以使它更优化你的查询有答案,这是正确的,虽然我的要求后来改变了。无论如何,谢谢你…投票赞成你的答案你能做吗如我所愿??是的,要求的哪一部分发生了变化?只是为了不使用太多的select语句,主要是消除UNION。您的查询工作正常,但它很重,所以我们可以使其更优化。您的查询有正确的答案,尽管我的要求后来发生了变化。无论如何,谢谢您……投票支持您的答案。您可以吗按我的意思做??是的,需求的哪一部分发生了变化?这只是为了不使用太多的select语句,主要是因为我的需求随着时间的推移而变化,现在我也有了一个地区栏,现在我必须根据每个地区、每个产品、每年和每个季度进行划分。在那之前,我的情况非常不同现在计算简单的平均销售额就完全不同了。所以,我试着通过你的例子在分区中添加区域和产品qtr,但是对于一些上一季度没有销售的产品,它会在上一季度的销售栏中显示其他产品的平均销售额,还有一件事,如果本季度没有销售,它应该是我在下一季度之前计算的上一个平均销售额最后一个条件,但不知道如何显示当前季度没有销售:(我已经编写了代码,但它不满足最后一个条件,即如果当前没有销售,则在该条件中应显示null,并在前一个平均值列中显示前一个销售平均值。我正在添加我的代码,如果您可以帮助更新答案并解释为什么您在回答中遇到困难。我放弃了您正在使用的方法。)因为这是太混乱和难以匹配的平均值和prv_平均值四分之一。享受!再次感谢朋友!但你没有得到我的观点无论如何谢谢你的回答我已经解决了我的问题。你的回答错过了我得到上一季度平均值的最后一点,如果本季度没有销售…如果我错过了这一点,这一点是不明确的;数据是you posted在创建的输出中准确表示。如果您有另一个解决方案更准确地回答您的问题,请将其发布,以便对您提出的问题有一个正确的答案。很抱歉,我的要求随着时间的推移而改变,现在我也有一个区域栏,现在我必须根据每个区域、每个产品进行分区,每年和每个季度。在那之前,它是非常不同的。我已经计算了简单的平均值,现在它是非常不同的。因此,我尝试通过您的示例在分区中添加区域和产品qtr,但是对于一些上一季度没有销售的产品,它在上一个销售列中显示其他产品的平均销售,如果没有销售,还有一件事在本季度,其应为我计算的上一个平均销售额,直到最后一个条件,但不知道如何显示本季度没有销售额:(我已经编写了代码,但它不满足最后一个条件,即如果当前没有销售,则在该条件中应显示null,并在前一个平均值列中显示前一个销售平均值。我正在添加我的代码,如果您可以帮助更新答案并解释为什么您在回答中遇到困难。我放弃了您正在使用的方法。)因为这是太混乱和难以匹配的平均值和prv_平均值四分之一。享受!再次感谢朋友!但你没有得到我的观点无论如何谢谢你的回答我已经解决了我的问题。你的回答错过了我得到上一季度平均值的最后一点,如果本季度没有销售…如果我错过了这一点,这一点是不明确的;数据是you posted在创建的输出中准确表示。如果您有另一个解决方案更准确地回答您的问题,请将其发布,以便为您提出的问题提供正确答案。
Region Product Year Qtr Month Sales
NORTH P1 2015 1 JAN 1000
NORTH P1 2015 1 FEB 2000
NORTH P1 2015 1 MAR 3000
NORTH P1 2015 2 APR 4000
NORTH P1 2015 2 MAY 5000
NORTH P1 2015 2 JUN 6000
NORTH P1 2015 3 JUL 7000
NORTH P1 2015 3 AUG 8000
NORTH P1 2015 3 SEP 9000
NORTH P1 2015 4 OCT 1000
NORTH P1 2015 4 DEC 4000
NORTH P1 2015 4 NOV 2000
NORTH P3 2015 1 FEB 1000
NORTH P3 2015 1 FEB 9000
NORTH P3 2015 2 APR 2000
NORTH P3 2015 3 JUL 8000
NORTH P1 2016 1 MAR 3000
NORTH P1 2016 1 FEB 1000
NORTH P1 2016 1 JAN 2000
SOUTH P1 2015 1 JAN 2000
SOUTH P1 2015 1 FEB 3000
SOUTH P1 2015 1 JAN 4000
SOUTH P2 2015 1 MAR 1000
SOUTH P2 2015 1 JAN 8000
SOUTH P2 2015 1 FEB 9000
SOUTH P2 2015 2 JUN 9000
SOUTH P2 2015 2 MAY 8000
SOUTH P2 2015 2 APR 2000
SOUTH P2 2015 3 SEP 4000
SOUTH P2 2015 3 AUG 2000
SOUTH P2 2015 3 JUL 1000
SOUTH P2 2015 4 NOV 2000
SOUTH P2 2015 4 DEC 1000
SOUTH P2 2015 4 OCT 5000
SOUTH P3 2015 3 AUG 9000
SOUTH P3 2015 4 OCT 1000
SOUTH P3 2015 4 NOV 3000
SOUTH P2 2016 1 JAN 2000
SOUTH P2 2016 1 JAN 4000
WITH AvgSales
AS (SELECT
region,
product,
year,
qtr,
ROUND(AVG(sales), 2) AS avg_Sale
FROM one
GROUP BY region,
product,
year,qtr
)
SELECT
s.region,
s.product,
s.year,
s.month,
s.sales,
avg.qtr,
avg.avg_Sale AS Qtr_Avg_Sale,
prev.avg_sale AS Prev_Qtr_Avg_Sale
FROM one s
JOIN AvgSales avg
ON s.region = avg.region
AND s.product = avg.product
AND s.QTR = avg.qtr
AND s.year = avg.year
LEFT JOIN AvgSales prev
ON (s.region = prev.region
AND s.product = prev.product
AND s.year - 1 = prev.year
and s.qtr=1
AND prev.qtr = 4) or
(s.region = prev.region
AND s.product = prev.product
AND s.year = prev.year
AND s.qtr - 1 = prev.qtr) ;
Region Product Year qtr month sale avg_Sale prev_avg_sale
NORTH P1 2015 1 JAN 1000 2000
NORTH P1 2015 1 FEB 2000 2000
NORTH P1 2015 1 MAR 3000 2000
NORTH P1 2015 2 APR 4000 5000 2000
NORTH P1 2015 2 MAY 5000 5000 2000
NORTH P1 2015 2 JUN 6000 5000 2000
NORTH P1 2015 3 JUL 7000 8000 5000
NORTH P1 2015 3 AUG 8000 8000 5000
NORTH P1 2015 3 SEP 9000 8000 5000
NORTH P1 2015 4 OCT 1000 2333.33 8000
NORTH P1 2015 4 NOV 2000 2333.33 8000
NORTH P1 2015 4 DEC 4000 2333.33 8000
SOUTH P2 2015 1 JAN 8000 6000
SOUTH P2 2015 1 FEB 9000 6000
SOUTH P2 2015 1 MAR 1000 6000
SOUTH P2 2015 2 APR 2000 6333.33 6000
SOUTH P2 2015 2 MAY 8000 6333.33 6000
SOUTH P2 2015 2 JUN 9000 6333.33 6000
SOUTH P2 2015 3 JUL 1000 2333.33 6333.33
SOUTH P2 2015 3 AUG 2000 2333.33 6333.33
SOUTH P2 2015 3 SEP 4000 2333.33 6333.33
SOUTH P2 2015 4 OCT 5000 2666.67 2333.33
SOUTH P2 2015 4 NOV 2000 2666.67 2333.33
SOUTH P2 2015 4 DEC 1000 2666.67 2333.33
NORTH P3 2015 1 FEB 9000 5000
NORTH P3 2015 1 FEB 1000 5000
NORTH P3 2015 2 APR 2000 2000 5000
NORTH P3 2015 3 JUL 8000 8000 2000
SOUTH P3 2015 3 AUG 9000 9000
SOUTH P3 2015 4 OCT 1000 2000 9000
SOUTH P3 2015 4 NOV 3000 2000 9000
NORTH P1 2016 1 JAN 2000 2000 2333.33
NORTH P1 2016 1 FEB 1000 2000 2333.33
NORTH P1 2016 1 MAR 3000 2000 2333.33
NORTH P2 2016 2 2000
SOUTH P2 2016 1 JAN 2000 3000 2666.67
SOUTH P2 2016 1 JAN 4000 3000 2666.67
SOUTH P2 2016 2 3000
SOUTH P1 2015 1 JAN 4000 3000
SOUTH P1 2015 1 JAN 2000 3000
SOUTH P1 2015 1 FEB 3000 3000
--handles when the current quarter being viewed is 2,3,or 4 because those would still be in the same year when looking at the previous quarter
select t1.product,
t1.year,
t1.month,
t1.sales ,
t1.qtr,
round(avg(t1.sales) over (partition by t1.qtr,t1.year),2) as av,
t2.prev_av
from one t1
left join ( select
product,
year,
month,
sales ,
qtr,
round(avg(sales) over (partition by qtr,year),2) as prev_av
from one
) t2
on t1.year = t2.year
and (t1.qtr - 1) = t2.qtr
where t1.qtr in (2,3,4)
union
--handles the 1st quarter of the year when you need to grab the 4th quarter of the previous year for the previous avg
select t3.product,
t3.year,
t3.month,
t3.sales ,
t3.qtr,
round(avg(t3.sales) over (partition by t3.qtr,t3.year),2) as av,
t4.prev_av
from one t3
left join ( select
product,
year,
month,
sales,
qtr,
round(avg(sales) over (partition by qtr,year),2) as prev_av
from one
) t4
on (t3.year - 1) = t4.year
and t4.qtr = 4
where t3.qtr = 1;
with t1 as (
select one.*
, dense_rank() over (order by year, qtr) qord
from one
)
select product
, year
, qtr
, month
, sales
, round(avg(sales) over (partition by qord),2) qtr_avg
, round(avg(sales) over (order by qord
range between 1 preceding
and 1 preceding),2) prev_qtr_avg
from t1
with qtrs as (select level qtr from dual connect by level <=4)
, t1 as (
select product
, year
, qtrs.qtr
, month
, sales
, dense_rank() over (order by year, qtrs.qtr) qord
from qtrs
left outer join one partition by (year)
on one.qtr = qtrs.qtr
)
select product
, year
, qtr
, month
, sales
, round(avg(sales) over (partition by qord),2) qtr_avg
, round(avg(sales) over (order by qord
range between 1 preceding
and 1 preceding),2) prev_qtr_avg
from t1
with t1 as (select one.*, year*4+qtr qord from one)
select product
, year
, qtr
, month
, sales
, round(avg(sales) over (partition by qord),2) qtr_avg
, round(avg(sales) over (order by qord
range between 1 preceding
and 1 preceding),2) prev_qtr_avg
from t1
with qtrs(qtr) as (select level from dual connect by level <= 4)
, t1 as (
select region, product, year, q.qtr, month, sales, year*4+q.qtr qord
from qtrs q
left join one partition by (region, product, year)
on q.qtr = one.qtr
)
select region
, product
, year
, qtr
, month
, sales
, round(avg(sales) over (partition by region, product, qord),2) avg_sale
, round(avg(sales) over (partition by region, product
order by qord
range between 1 preceding
and 1 preceding),2) prev_avg_sale
from t1
order by year, region, qtr, product;
--Build the test table
IF OBJECT_ID('SALES','U') IS NOT NULL
DROP TABLE SALES
CREATE TABLE SALES
(
Region VARCHAR(255)
, Product VARCHAR(10)
, [Year] INT
, QTR INT
, [Month] VARCHAR(19)
, Sales DECIMAL(19,4)
);
INSERT SALES
VALUES
('NORTH', 'P1', 2015, 1, 'JAN', 1000)
,('NORTH', 'P1', 2015, 1, 'FEB', 2000)
,('NORTH', 'P1', 2015, 1, 'MAR', 3000)
,('NORTH', 'P1', 2015, 2, 'APR', 4000)
,('NORTH', 'P1', 2015, 2, 'MAY', 5000)
,('NORTH', 'P1', 2015, 2, 'JUN', 6000)
,('NORTH', 'P1', 2015, 3, 'JUL', 7000)
,('NORTH', 'P1', 2015, 3, 'AUG', 8000)
,('NORTH', 'P1', 2015, 3, 'SEP', 9000)
,('NORTH', 'P1', 2015, 4, 'OCT', 1000)
,('NORTH', 'P1', 2015, 4, 'DEC', 4000)
,('NORTH', 'P1', 2015, 4, 'NOV', 2000)
,('NORTH', 'P3', 2015, 1, 'FEB', 1000)
,('NORTH', 'P3', 2015, 1, 'FEB', 9000)
,('NORTH', 'P3', 2015, 2, 'APR', 2000)
,('NORTH', 'P3', 2015, 3, 'JUL', 8000)
,('NORTH', 'P1', 2016, 1, 'MAR', 3000)
,('NORTH', 'P1', 2016, 1, 'FEB', 1000)
,('NORTH', 'P1', 2016, 1, 'JAN', 2000)
,('SOUTH', 'P1', 2015, 1, 'JAN', 2000)
,('SOUTH', 'P1', 2015, 1, 'FEB', 3000)
,('SOUTH', 'P1', 2015, 1, 'JAN', 4000)
,('SOUTH', 'P2', 2015, 1, 'MAR', 1000)
,('SOUTH', 'P2', 2015, 1, 'JAN', 8000)
,('SOUTH', 'P2', 2015, 1, 'FEB', 9000)
,('SOUTH', 'P2', 2015, 2, 'JUN', 9000)
,('SOUTH', 'P2', 2015, 2, 'MAY', 8000)
,('SOUTH', 'P2', 2015, 2, 'APR', 2000)
,('SOUTH', 'P2', 2015, 3, 'SEP', 4000)
,('SOUTH', 'P2', 2015, 3, 'AUG', 2000)
,('SOUTH', 'P2', 2015, 3, 'JUL', 1000)
,('SOUTH', 'P2', 2015, 4, 'NOV', 2000)
,('SOUTH', 'P2', 2015, 4, 'DEC', 1000)
,('SOUTH', 'P2', 2015, 4, 'OCT', 5000)
,('SOUTH', 'P3', 2015, 3, 'AUG', 9000)
,('SOUTH', 'P3', 2015, 4, 'OCT', 1000)
,('SOUTH', 'P3', 2015, 4, 'NOV', 3000)
,('SOUTH', 'P2', 2016, 1, 'JAN', 2000)
,('SOUTH', 'P2', 2016, 1, 'JAN', 4000);
--CTE TO CAPTURE AVG SALES BY REGION, PRODCUT, YEAR, QTR; OMIT PRODUCT IF YOU WANT STRAIGHT UP QUARTER AVG, REGARDLESS OF PRODCUCT
WITH cteAvgSales AS
(
SELECT Region, Product, [Year], QTR, AVG(Sales) current_avg
, RANK() OVER(ORDER BY Region, Product, [Year], QTR) AS RNK
FROM SALES
GROUP BY Region, Product, [Year], QTR
)
SELECT s.Region, s.Product, s.[Year] AS [year], s.QTR AS [quarter], s.[Month], s.Sales, a.current_avg, p.current_avg AS previous_avg
FROM SALES s
INNER JOIN cteAvgSales a ON a.Region = s.Region
AND a.Product = s.Product
AND a.[Year] = s.[Year]
AND a.QTR = s.QTR
LEFT JOIN cteAvgSales p ON p.Region = a.Region
AND p.Product = s.Product
AND p.RNK=a.RNK-1
ORDER BY s.Region, s.Product, s.[Year], s.QTR