2016-05-04 62 views
0

我擁有的: 每個產品每日營業額的表。Oracle SQL - 本週的平均營業額高於去年的平均每週營業額

我需要的是: 提取本週平均每日營業額大於上一年(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); 
+0

請添加一些示例數據和您的查詢的預期輸出 - 您的要求不是100%清楚(至少不是我)。 –

回答

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:

在語法上,查詢獲取的結果,但是弗蘭克提到你的邏輯似乎有點過

表內容

+------+----------+------+-----------+ 
| 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); 

結果

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

如果我正確理解OP,那麼這兩者都不會返回正確的行 - 您將蘋果與橙子進行比較(過去一年每週AVG對於所有其他產品而不是相同產品的上週AVG產品)。 –

+0

我需要比較整個最近52周的每週營業額與相同產品當前周的平均每週營業額(比較product_one的每年一次到product_one的每週一次,product_two到product_two等)。我需要一份周銷量高於過去52周平均每週營業額的產品清單。 –

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); 

這將解決您的「單行子查詢...」錯誤。然而,我不是100%確定你的邏輯是正確的 - 你真的想每天比較每天平均值與每週(即7天以上)之間的平均值嗎?