简体   繁体   中英

How do i select only a column from my sub-query with aggregate function?

I have data in below format.

在此处输入图像描述

Q. Find the average and total revenue by each subcategory for the categories which are among top 5 categories in terms of quantity sold.

I wrote code mentioned below.

Now, I know that my subquery has an aggregate function and the column i want. I want the output to be only column "PROD_CAT_CODE" but also want the sum of quantities in sub query as it helps me in finding out the prod cat code with most quantities sold.

SELECT      PROD_SUBCAT_CODE, SUM(TOTAL_AMT)[SUM], AVG(TOTAL_AMT)[AVG]
FROM        TRANSACTIONS
WHERE       PROD_CAT_CODE = (
                            SELECT      
                            TOP 5       PROD_CAT_CODE, SUM(T1.QTY) [Quantity Sold]
                            FROM        TRANSACTIONS
                            GROUP BY    PROD_CAT_CODE
                            ORDER BY    SUM(T1.QTY)
                            DESC
                            )
GROUP BY    PROD_SUBCAT_CODE
ORDER BY    PROD_SUBCAT_CODE

Thanks in advance.

You could use an inner join on subquery

  SELECT      PROD_SUBCAT_CODE, SUM(TOTAL_AMT)[SUM], AVG(TOTAL_AMT)[AVG]
  FROM        TRANSACTIONS
  INNER JOIN (
        SELECT      
        TOP 5       PROD_CAT_CODE, SUM(T1.QTY) [Quantity Sold]
        FROM        TRANSACTIONS
        GROUP BY    PROD_CAT_CODE
        ORDER BY    SUM(T1.QTY)
        DESC
        ) T ON T.PROD_CAT_CODE = TRANSACTIONS.PROD_CAT_CODE
  GROUP BY    PROD_SUBCAT_CODE
  ORDER BY    PROD_SUBCAT_CODE

I would use window functions. Here is one method:

select top (1) with ties prod_cat_code, prod_subcat_code,
       total_amt, avg_total_amt
from (select prod_cat_code, prod_subcat_code, sum(total_amt) as total_amt,
             avg(total_amt) as avg_total_amt,
             sum(sum(qty)) over (partition by prod_cat_code) as category_sum
      from transactions t
      group by prod_cat_code, prod_subcat_code
     ) cs
order by dense_rank() over (order by category_sum desc, prod_cat_code);

EDIT:

You can also take your approach. Your query just needs a few fixer-uppers:

SELECT PROD_CAT_CODE, PROD_SUBCAT_CODE,
       SUM(TOTAL_AMT) as [SUM], AVG(TOTAL_AMT) as [AVG]
FROM TRANSACTIONS t
WHERE t.PROD_CAT_CODE IN (SELECT TOP 5 t2.PROD_CAT_CODE
                          FROM TRANSACTIONS t2
                          GROUP BY t2.PROD_CAT_CODE
                          ORDER BY SUM(T2.QTY) DESC
                         )
GROUP BY PROD_CAT_CODE, PROD_SUBCAT_CODE
ORDER BY PROD_CAT_CODE, PROD_SUBCAT_CODE;

The major issues with your query:

  • Use IN instead of = with the subquery.
  • Return only one column with the subquery.
  • Include PROD_CAT_CODE in the outer query, for both the SELECT and GROUP BY .
  • Use table aliases to distinguish the table references in the subquery and the outer query.

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM