I\'m trying to get a percentage of the itemid that are available in a certain area.
Using my query, I get an error ORA-00937: not a single-group group function<
I guess even this helps:
SELECT
distinct areas,
NVL(x.count_item * 100,0) AS Percentage
FROM
allitems a
LEFT OUTER JOIN (
SELECT
( COUNT(a.itemid) / (
SELECT
COUNT(*)
FROM
allitems
) ) AS count_item,
areas AS avl_areas
FROM
allitems a
INNER JOIN currentitems c ON a.itemid = c.itemid
GROUP BY
areas
) x ON x.avl_areas = a.areas
;
Just for the heck of it, a way of doing it without analytics.
Jeffrey's solution needed a DISTINCT because of the duplication of areas. The allitems table is actually an intersection table between currentitems and a putative areas table. In the following query this is represented by the inline view ai. There is another inline view tot which gives us the total number number of records in allitems. This count has to be included in the GROUP BY clause, as it is not an aggregating projector.
SQL> select ai.areas
2 , (count(currentitems.itemid)/tot.cnt) * 100 as "%"
3 from
4 ( select count(*) as cnt from allitems ) tot
5 , ( select distinct areas as areas from allitems ) ai
6 , currentitems
7 , allitems
8 where allitems.areas = ai.areas
9 and allitems.itemid = currentitems.itemid(+)
10 group by ai.areas, tot.cnt
11 /
AREAS %
-------------------- ----------
east 50
south 25
west 0
SQL>
I don't know whether this approach would perform better than Jeffrey's solution: it quite possibly will perform worse (the analytics query certainly has fewer consistent gets). It is interesting simply because it highlights the issues more clearly.
Here is a quick first pass:
select ai.areas,
(sum(cnt) / max(tot)) * 100 "Percentage Result"
from (select ai.itemid,
ai.areas,
count(ci.itemid) cnt,
count(ai.areas) over () tot
from allitems ai
left outer join
currentitems ci on (ai.itemid = ci.itemid)
group by ai.itemid, ai.areas
) ai
group by ai.areas
Also, in your test data your itemid 4 needs to be changed to west.
Analytics are your friend:
SELECT DISTINCT
areas
,COUNT(currentitems.itemid)
OVER (PARTITION BY areas) * 100
/ COUNT(*) OVER () Percentage
FROM allitems, currentitems
WHERE allitems.itemid = currentitems.itemid(+);
A slight modification of your original query :
Select
areas,
(
Select
Count(*)
From
Allitems Inner_Allitems Left Join Currentitems On (Currentitems.Itemid = Inner_Allitems.Itemid)
Where inner_allitems.areas = outer_allitems.areas
) *100 / (Select Count(*) From allitems ) as percentage
From allitems outer_allitems
Group By areas
Use Group 'By clause':
Select department_id, min(salary)
From employees
Group By department_id
Having min(salary) >
(
Select min(salary)
From employees
Where department_id <> 50
);