Oracle SQL - 本周的平均营业额高于去年的平均每周营业额

时间:2016-05-04 09:15:06

标签: sql oracle subquery oracle-sqldeveloper

我拥有的: 每个产品每日营业额的表格。

我需要什么: 提取当周平均每日营业额大于去年(52周)平均每周营业额的产品名称和价值。

不幸的是,oracle说单行子查询返回多行,我不知道我做错了什么。

SELECT NAME, AVG(TURNOVER)/52
FROM DAILY_STATS
WHERE TYPE=243 AND T_DATE >= SYSDATE - 365
GROUP BY NAME
HAVING AVG(TURNOVER)/52 > 0 
AND 
AVG(TURNOVER) > 
(SELECT AVG(TURNOVER)
FROM DAILY_STATS
WHERE TYPE=243 AND T_DATE >= TO_DATE(TRUNC(sysdate, 'DAY'),'DD/MM/YYYY')
GROUP BY NAME);

2 个答案:

答案 0 :(得分:0)

SELECT AVG(TURNOVER)
FROM DAILY_STATS
WHERE TYPE=243 AND T_DATE >= TO_DATE(TRUNC(sysdate, 'DAY'),'DD/MM/YYYY')
GROUP BY NAME

您的子查询返回多个值。

AVG(TURNOVER) >此处>运算符是标量运算符,只能比较一个值。

可能的解决方案

AVG(TURNOVER) > all
(SELECT AVG(TURNOVER)
FROM DAILY_STATS
WHERE TYPE=243 AND T_DATE >= TO_DATE(TRUNC(sysdate, 'DAY'),'DD/MM/YYYY')
GROUP BY NAME);

OR

AVG(TURNOVER) > ANY
(SELECT AVG(TURNOVER)
FROM DAILY_STATS
WHERE TYPE=243 AND T_DATE >= TO_DATE(TRUNC(sysdate, 'DAY'),'DD/MM/YYYY')
GROUP BY NAME);

运算符> ANY> all将标量运算符转换为多行运算符。 请注意,这可能符合您的逻辑,也可能不符合您的逻辑。

编辑:回答太早了。现在纠正。

EDIT2:

从语法上讲,查询获取结果,但是Frank提到你的逻辑似乎有点偏离

表格内容

+------+----------+------+-----------+
| NAME | TURNOVER | TYPE |  T_DATE   |
+------+----------+------+-----------+
| ABC  |      100 |    2 | 03-MAY-16 |
| ABD  |      200 |    2 | 02-MAY-16 |
| ABE  |      300 |    2 | 01-MAY-16 |
| ABF  |      400 |    2 | 30-APR-16 |
| ABF  |      500 |    2 | 29-APR-16 |
| ABG  |      600 |    2 | 28-APR-16 |
| ABH  |      700 |    3 | 27-APR-16 |
| ABH  |      800 |    2 | 28-APR-16 |
| ABH  |      900 |    2 | 28-APR-16 |
| ABH  |     1900 |    2 | 28-APR-16 |
| ABH  |     2900 |    2 | 28-APR-16 |
| ABH  |     3900 |    2 | 28-APR-16 |
| ABH  |   113900 |    2 | 28-APR-16 |
| ABH  |  1213900 |    2 | 28-APR-16 |
+------+----------+------+-----------+

<强>查询

SELECT NAME, AVG(TURNOVER)/52
FROM DAILY_STATS
WHERE TYPE=2 AND T_DATE >= SYSDATE - 365
GROUP BY NAME
HAVING AVG(TURNOVER)/52 > 0 
AND 
AVG(TURNOVER) > any
(SELECT AVG(TURNOVER)
FROM DAILY_STATS
WHERE TYPE=2 AND T_DATE >= sysdate-7
GROUP BY NAME);

<强> RESULT

+------+-------------------------------------------+
| NAME |             AVG(TURNOVER)/52              |
+------+-------------------------------------------+
| ABG  | 11.53846153846153846153846153846153846154 |
| ABD  | 3.84615384615384615384615384615384615385  |
| ABE  | 5.76923076923076923076923076923076923077  |
| ABF  | 8.65384615384615384615384615384615384615  |
| ABH  | 3676.373626373626373626373626373626373627 |
+------+-------------------------------------------+

答案 1 :(得分:0)

您没有正确过滤标量子查询的输入数据 - 因为您想要比较同一产品的平均值,您需要按产品名称进行过滤:

with daily_stats(type, t_date, turnover, name) as (
  select 243, date '2016-01-01', 200, 'P' from dual union all
  select 243, date '2016-05-04', 300, 'P' from dual union all
  select 243, date '2016-01-01', 200, 'Q' from dual)   
SELECT NAME, AVG(TURNOVER)/52
  FROM DAILY_STATS ds1
 WHERE TYPE=243 AND T_DATE >= SYSDATE - 365
GROUP BY NAME
HAVING AVG(TURNOVER)/52 > 0 
AND 
AVG(ds1.TURNOVER) <
(SELECT AVG(ds2.TURNOVER)
 FROM DAILY_STATS ds2
 WHERE ds2.TYPE=243 AND ds2.T_DATE >= TO_DATE(TRUNC(sysdate, 'DAY'),'DD/MM/YYYY')
 and ds2.name = ds1.name);

这将解析您的&#34;单行子查询......&#34;错误。但是,我并非100%确定您的逻辑是合理的 - 您是否真的想将每日平均值与每周(即超过7天)进行比较?