我查询'销售'表格为'价格',按产品名称分组:
SELECT product_name, sale_price, sale_date,
SUM(CASE WHEN sales.sale_date = TO_DATE ('14-JUN-14', 'DD-MON-YY') - 1 THEN (sale_price) ELSE 0 END) sale_yday,
SUM(CASE WHEN sales.sale_date = TO_DATE ('14-JUN-14', 'DD-MON-YY') - 7 THEN (sale_price) ELSE 0 END) sale_lweek,
AVG(sales.sale_price) ten_wk_avg,
STDDEV(sales.sale_price) ten_wk_stddev
FROM sales
WHERE sales.sale_date IN
(TO_DATE ('14-JUN-14', 'DD-MON-YY'),
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 1,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 2 * 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 3 * 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 4 * 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 5 * 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 6 * 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 7 * 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 8 * 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 9 * 7,
TO_DATE ('14-JUN-14', 'DD-MON-YY') - 10 * 7)
GROUP BY sales.product_name
AVG功能并没有按照我需要做的事情 - 我需要它平均只采用前10周,而不是之前的10周PLUS今天和昨天如上所述。与标准偏差相同的情况。有没有更好的方法来构建此查询,以便我可以按照描述获得ten_wk_avg和ten_wk_stddev?
答案 0 :(得分:1)
使用条件聚合:
SELECT product_name, sale_price, sale_date,
SUM(CASE WHEN sales.sale_date = TO_DATE('14-JUN-14', 'DD-MON-YY') - 1 THEN (sale_price) ELSE 0
END) as sale_yday,
SUM(CASE WHEN sales.sale_date = TO_DATE('14-JUN-14', 'DD-MON-YY') - 7 THEN (sale_price) ELSE 0
END) as sale_lweek,
AVG(CASE WHEN sales.sale_date < TO_DATE('14-JUN-14', 'DD-MON-YY') - 1 THEN sales.sale_price
END) as ten_wk_avg,
STDDEV(CASE WHEN sales.sale_date < TO_DATE('14-JUN-14', 'DD-MON-YY') - 1 THEN sales.sale_price
END) as ten_wk_stddev
. . .
avg()
和stddev()
忽略NULL
值,这就是else
中没有case
子句的原因。
答案 1 :(得分:0)
首先,您应该考虑在查询中要求的内容。您想要过去10周内每次促销的product_name,sale_price和sale_date。这可能是数十,数百或数千的销售。那么你想要(每个产品)昨天的销售额,上周的销售额以及过去10周的销售额的平均值和标准差。这些是每种产品的单一价值,但它们将会一遍又一遍地重复几十次,数百次或数千次。这真的是你想要的吗?
这是一个查询,它将为您提供所需的汇总值 - 每个产品一行。如果您想看到它的实际效果,请尝试SQL Fiddle检查。它可能不是最紧凑的查询,但是它被分解为很容易遵循的块状态。
WITH
By_Week AS(
SELECT product_name, sale_date, sale_price,
trunc(sale_date, 'd') as week_of,
(trunc(SYSDATE, 'd') - trunc(sale_date, 'd')) / 7 AS weeks_ago
FROM sales
),
Weekly_Sales AS(
SELECT product_name,
sum( CASE WHEN weeks_ago BETWEEN 1 AND 10 THEN sale_price END ) AS ten_wk_avg,
stddev( case when weeks_ago between 1 and 10 then sale_price end ) AS ten_wk_stddev
FROM By_Week
group by product_name
)
SELECT w.product_name,
sum( CASE WHEN trunc(SYSDATE) - w.sale_date = 1 THEN w.sale_price END ) AS sale_yday,
sum( CASE WHEN weeks_ago = 1 THEN sale_price END ) AS sale_lweek,
s.ten_wk_avg, s.ten_wk_stddev
FROM By_Week w
JOIN Weekly_Sales s
ON s.product_name = w.product_name
GROUP BY w.product_name, s.ten_wk_avg, s.ten_wk_stddev
order by w.product_name;
顺便说一句,你已经标记了Oracle和MySQL。上面的查询适用于Oracle。 MySQL没有CTE(iirc),但你可以把它们作为内联视图。