Home > OS >  Return second from the last oracle sql
Return second from the last oracle sql

Time:11-18

SELECT * FROM
          (
           SELECT DISTINCT(TRUNC(receipt_dstamp)) 
           FROM inventory
           WHERE substr(location_id,1,3) = 'GI-'
           ORDER BY 1 ASC 
          )
           WHERE ROWNUM <= 5

Output: enter image description here

Hi all, i've got this subeqery and in this case my oldest date is in row 1, i want to retrive only second from the last(from the top in this case) which is gonna be 01-SEP-21. I was trying to play with ROWNUM and OVER but without any results, im getting blank output.

Thank you.

Full query:

SELECT TRUNC(receipt_dstamp) as old_putaway_date, COUNT(tag_id) as tag_old_putaway
    FROM inventory
WHERE substr(location_id,1,3) = 'GI-' 
AND TRUNC(receipt_dstamp) IN (  
                                SELECT * FROM
                                (
                                    SELECT DISTINCT(TRUNC(receipt_dstamp)) 
                                    FROM inventory
                                    WHERE substr(location_id,1,3) = 'GI-'
                                    ORDER BY 1 ASC 
                                )
                                WHERE ROWNUM = 1
                              )
GROUP BY TRUNC(receipt_dstamp);

CodePudding user response:

You should be able to simplify the entire query to:

SELECT old_putaway_date,
       COUNT(tag_id) as tag_old_putaway
FROM   (
  SELECT TRUNC(receipt_dstamp) as old_putaway_date,
         tag_id,
         DENSE_RANK() OVER (ORDER BY TRUNC(receipt_dstamp)) AS rnk
  FROM   inventory
  WHERE substr(location_id,1,3) = 'GI-'
)
WHERE rnk = 3
GROUP BY
       old_putaway_date;

CodePudding user response:

You can use dense_rank() :

SELECT * FROM (
SELECT L.*,DENSE_RANK() 
OVER (PARTITION BY L.TAG_OLD_PUTAWAY ORDER BY L.OLD_PUTAWAY_DATE DESC) RNK 
FROM 
(
SELECT TRUNC(receipt_dstamp) as old_putaway_date, COUNT(tag_id) as tag_old_putaway
    FROM inventory
WHERE substr(location_id,1,3) = 'GI-' 
AND TRUNC(receipt_dstamp) IN (  
                                SELECT * FROM
                                (
                                    SELECT DISTINCT(TRUNC(receipt_dstamp)) 
                                    FROM inventory
                                    WHERE substr(location_id,1,3) = 'GI-'
                                    ORDER BY 1 ASC 
                                )
                                WHERE ROWNUM = 1
                              )
GROUP BY TRUNC(receipt_dstamp)
) L
) WHERE RNK = 2 

CodePudding user response:

You are using an old Oracle syntax that is not standard compliant in the regard that it relies on a subquery result order. (Sub)query results are unordered data sets by definition, but Oracle lets this pass in order to make their ROWNUM work with it.

Oracle now supports the standard SQL FETCH clause, which you should use instead.

SELECT DISTINCT TRUNC(receipt_dstamp) AS receipt_date
FROM inventory
WHERE SUBSTR(location_id, 1, 3) = 'GI-'
ORDER BY receipt_date
OFFSET 2 ROWS
FETCH NEXT 1 ROW ONLY;

https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/SELECT.html#GUID-CFA006CA-6FF1-4972-821E-6996142A51C6

  • Related