Using a pl-sql procedure or cursor to select top 3 rank

亡梦爱人 提交于 2019-12-25 04:38:37

问题


Can someone please tell how can I get the results as below.

Using dense_rank function where rank <=2 will give me top 2 offers.

I am also looking to get 'total_offer' which should be sum of 'offer1' and 'offer2'. when there is no offer2 ( eg:taurus) 'total offer' should be 'offer1' and 'null' for 'offer2'

Input:

customer    make    zipcode offer
mark            focus   101 250  
mark             focus  101 2500  
mark             focus  101 1000  
mark             focus  101 1500  
henry   520i    21405   500  
henry   520i    21405   100  
henry   520i    21405   750  
henry   520i    21405   100  
mark            taurus  48360   250    
mark            mustang 730 500  
mark            mustang 730 1000  
mark            mustang 730 1250  

Desired Output:

 | CUSTOMER | MAKE | ZIPCODE | TOP_OFFER1 | TOP_OFFER2 | Total_offer |  
 | henry | 520i | 21405 | 750 | 500 | 1250  
 | mark | focus | 101 | 2500 | 1500 | 4000  
 | mark | mustang | 730 | 1250 | 1000 | 2250  
 | mark | taurus | 48360 | 250 | NULL| 250 |   

回答1:


Try this....

select * from (
select customer,make,zipcode,offer, dense_rank() over (PARTITION by customer order by customer,make, zipcode,offer desc) Rank from tablename)
where Rank <4;



回答2:


SQL Fiddle

Oracle 11g R2 Schema Setup:

CREATE TABLE TEST ( customer, make, zipcode, offer ) AS
          SELECT 'mark',  'focus',    101,  250 FROM DUAL
UNION ALL SELECT 'mark',  'focus',    101, 2500 FROM DUAL
UNION ALL SELECT 'mark',  'focus',    101, 1000 FROM DUAL
UNION ALL SELECT 'mark',  'focus',    101, 1500 FROM DUAL
UNION ALL SELECT 'henry', '520i',   21405,  500 FROM DUAL
UNION ALL SELECT 'henry', '520i',   21405,  100 FROM DUAL
UNION ALL SELECT 'henry', '520i',   21405,  750 FROM DUAL
UNION ALL SELECT 'henry', '520i',   21405,  100 FROM DUAL
UNION ALL SELECT 'mark',  'taurus', 48360,  250 FROM DUAL
UNION ALL SELECT 'mark',  'mustang',  730,  500 FROM DUAL
UNION ALL SELECT 'mark',  'mustang',  730, 1000 FROM DUAL
UNION ALL SELECT 'mark',  'mustang',  730, 1250 FROM DUAL;

Query 1 - If you want at most 3 rows per group::

WITH ranks AS (
  SELECT t.*,
         ROW_NUMBER() OVER ( PARTITION BY CUSTOMER, MAKE, ZIPCODE ORDER BY OFFER DESC ) AS RANK
  FROM   TEST t
)
SELECT *
FROM   RANKS
WHERE  RANK <= 3

Results:

| CUSTOMER |    MAKE | ZIPCODE | OFFER | RANK |
|----------|---------|---------|-------|------|
|    henry |    520i |   21405 |   750 |    1 |
|    henry |    520i |   21405 |   500 |    2 |
|    henry |    520i |   21405 |   100 |    3 |
|     mark |   focus |     101 |  2500 |    1 |
|     mark |   focus |     101 |  1500 |    2 |
|     mark |   focus |     101 |  1000 |    3 |
|     mark | mustang |     730 |  1250 |    1 |
|     mark | mustang |     730 |  1000 |    2 |
|     mark | mustang |     730 |   500 |    3 |
|     mark |  taurus |   48360 |   250 |    1 |

Query 2 - If you want the top 3 ranks including ties:

WITH ranks AS (
  SELECT t.*,
         DENSE_RANK() OVER ( PARTITION BY CUSTOMER, MAKE, ZIPCODE ORDER BY OFFER DESC ) AS RANK
  FROM   TEST t
)
SELECT *
FROM   RANKS
WHERE  RANK <= 3

Results:

| CUSTOMER |    MAKE | ZIPCODE | OFFER | RANK |
|----------|---------|---------|-------|------|
|    henry |    520i |   21405 |   750 |    1 |
|    henry |    520i |   21405 |   500 |    2 |
|    henry |    520i |   21405 |   100 |    3 |
|    henry |    520i |   21405 |   100 |    3 |
|     mark |   focus |     101 |  2500 |    1 |
|     mark |   focus |     101 |  1500 |    2 |
|     mark |   focus |     101 |  1000 |    3 |
|     mark | mustang |     730 |  1250 |    1 |
|     mark | mustang |     730 |  1000 |    2 |
|     mark | mustang |     730 |   500 |    3 |
|     mark |  taurus |   48360 |   250 |    1 |


来源:https://stackoverflow.com/questions/31597182/using-a-pl-sql-procedure-or-cursor-to-select-top-3-rank

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!