I have a table (STUFF) with 3 columns (item, old_value, new_value). I would like to retrieve all the items with the highest percentage change in value. The following query produces a "group function is not allowed here" error. How do I go about fixing this?
SELECT item,
old_value,
new_value,
highest_percentage
FROM (SELECT item, old_value, new_value,
(new_value - old_value) / old_value * 100 AS highest_percentage
FROM STUFF)
WHERE highest_percentage = MAX(highest_percentage);
This is the table
CREATE TABLE STUFF
( item VARCHAR2(30) PRIMARY KEY,
old_value NUMBER(6, 2),
new_value NUMBER(6, 2));
INSERT INTO STUFF VALUES('E1', 0.62, 1.78);
INSERT INTO STUFF VALUES('B1', 0.80, 3.28);
INSERT INTO STUFF VALUES('B2', 2.72, 7.36);
INSERT INTO STUFF VALUES('M4', 2.70, 5.65);
INSERT INTO STUFF VALUES('T6', 5.70, 6.65);
INSERT INTO STUFF VALUES('R3', 4.00, 16.40);
INSERT INTO STUFF VALUES('G10', 8.00, 32.80);
Ideally I should have this output.
ITEM OLD_VALUE NEW_VALUE HIGHEST_PERCENTAGE
------------------- --------- --------- ------------------
B1 0.80 3.28 310
G10 8.00 32.80 310
R3 4.00 16.40 310
It's called a Top-N query in Oracle you can do it like:
select * from
(select * from XXX order by YYY desc)
where rownum < N;
According to your latest update - a scalar sub-query helps in this case:
SELECT * FROM STUFF
WHERE (new_value - old_value) / old_value * 100 =
(SELECT max((new_value - old_value) / old_value * 100) AS highest_percentage
FROM STUFF)
To avoid extra sub-querying:
SELECT * FROM
STUFF,
(SELECT max((new_value - old_value) / old_value * 100) AS percentage FROM STUFF) highest
WHERE (new_value - old_value) / old_value * 100 = highest.percentage ;
However Analytic function seems to be the fastest solution.
Another option is to use a window function that calculates the max percentage while retrieving the data. This is probably faster than the solution with a sub-query as the table only needs to be accessed once:
with data as (
SELECT item,
old_value,
new_value,
(new_value - old_value) / old_value * 100 AS highest_percentage,
max((new_value - old_value) / old_value * 100) over () as max_pct
FROM STUFF
)
SELECT item,
old_value,
new_value,
highest_percentage
FROM data
WHERE highest_percentage = max_pct;
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.