How to resolve ORA-00937: not a single-group group function when calculating percentage?

后端 未结 6 1710
不思量自难忘°
不思量自难忘° 2021-01-18 05:08

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<

相关标签:
6条回答
  • 2021-01-18 05:23

    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
    ;
    
    0 讨论(0)
  • 2021-01-18 05:26

    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.

    0 讨论(0)
  • 2021-01-18 05:27

    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.

    0 讨论(0)
  • 2021-01-18 05:36

    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(+);
    
    0 讨论(0)
  • 2021-01-18 05:37

    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
    
    0 讨论(0)
  • 2021-01-18 05:37

    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
    );
    
    0 讨论(0)
提交回复
热议问题