skip to Main Content

I have a transaction table, I want to get the product ID of the record which is ranked 3rd highest for sales. Please note there there can be multiple transactions for an item and one transaction can have multiple qty. so i am wanting to find which product id has the 3rd highest qty.

I think i need to use something like rank, but my query returns ranks weirdly, not sure whats wrong.

select distinct t.product_id,
  sum(t.qty) over (partition by t.product_id) qty, 
  rank() over(partition by t.product_id order by t.qty desc) rnk
from transaction t
order by rnk`

CREATE TABLE IF NOT EXISTS "transaction"
  (DATE_ID             BIGINT NOT NULL,
   STORE_ID            INT NOT NULL,
   TRANSACTION_TYPE_ID CHAR(1) NOT NULL,
   PRODUCT_ID          INT NOT NULL,
   QTY                 INT NOT NULL);

INSERT INTO "transaction"
  (DATE_ID, STORE_ID, TRANSACTION_TYPE_ID, PRODUCT_ID, QTY)
VALUES
  (1, 1, 'A', 1, 2),
  (1, 1, 'B', 1, 1),
  (1, 2, 'A', 4, 1),
  (1, 6, 'A', 3, 1),
  (1, 1, 'A', 1, 1),
  (2, 1, 'B', 1, 1),
  (2, 1, 'A', 1, 1),
  (2, 2, 'A', 2, 5),
  (3, 2, 'A', 2, 7),
  (3, 3, 'A', 2, 1),
  (3, 3, 'B', 1, 15),
  (3, 3, 'A', 1, 1),
  (4, 4, 'A', 1, 1),
  (4, 4, 'A', 1, 5),
  (4, 4, 'A', 1, 11),
  (4, 5, 'A', 3, 2),
  (4, 6, 'A', 3, 1),
  (4, 6, 'A', 3, 1),
  (4, 6, 'B', 2, 1),
  (5, 2, 'A', 2, 2),
  (5, 2, 'B', 1, 1),
  (5, 2, 'A', 2, 1),
  (5, 2, 'A', 4, 1),
  (5, 2, 'A', 5, 1),
  (6, 2, 'B', 4, 1),
  (6, 2, 'A', 6, 1),
  (6, 3, 'A', 3, 5),
  (7, 3, 'A', 2, 7),
  (7, 4, 'A', 2, 1),
  (7, 4, 'B', 2, 15),
  (7, 4, 'A', 2, 1),
  (7, 5, 'A', 2, 1),
  (7, 5, 'A', 2, 5),
  (7, 5, 'A', 2, 11),
  (7, 6, 'A', 2, 2),
  (7, 1, 'A', 2, 1),
  (8, 1, 'A', 2, 1),
  (8, 1, 'B', 2, 1),
  (8, 3, 'A', 3, 2),
  (9, 3, 'B', 3, 1),
  (9, 3, 'A', 3, 1),
  (9, 3, 'A', 3, 1),
  (9, 3, 'A', 3, 1),
  (10, 3, 'B', 3, 1),
  (10, 3, 'A', 3, 1),
  (10, 4, 'A', 4, 5),
  (10, 4, 'A', 4, 7),
  (10, 5, 'A', 5, 1),
  (10, 5, 'B', 5, 15),
  (10, 5, 'A', 5, 1),
  (10, 6, 'A', 6, 1),
  (10, 6, 'A', 6, 5),
  (10, 6, 'A', 6, 11),
  (10, 1, 'A', 1, 2),
  (10, 2, 'A', 2, 1),
  (11, 2, 'A', 2, 1),
  (11, 2, 'B', 2, 1),
  (11, 3, 'A', 5, 2),
  (11, 3, 'B', 5, 1),
  (11, 3, 'A', 5, 1),
  (12, 3, 'A', 5, 1),
  (12, 3, 'A', 5, 1)

2

Answers


  1. select  product_id
    from    (
            select   product_id
                    ,dense_rank() over(order by sum(qty)) as d_rnk
            from     transaction
            group by product_id 
            ) t
    where   d_rnk = 3
    
    product_id
    5

    Fiddle

    Login or Signup to reply.
  2. Yet another option is:

    • aggregating the "qty" values per "product_id" (SUM(qty) GROUP BY product_id)
    • extracting a ranking value for each product_id summed quantities (DENSE_RANK() OVER(ORDER BY SUM(qty) DESC))
    • ordering your output rows with respect to when this ranking value equals 3 (DENSE_RANK() ... = 3)
    • keeping only the first row given your ordering (FETCH FIRST 1 ROWS WITH TIES )
    SELECT product_id
    FROM "transaction"
    GROUP BY product_id
    ORDER BY DENSE_RANK() OVER(ORDER BY SUM(qty) DESC) = 3 DESC
    FETCH FIRST 1 ROWS WITH TIES 
    

    Check the demo here.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search