SQL to group the records and apply logic to pick one record from each group

Hi Friends,
I am looking for a query to group the records on certain columns in a table and then from each group I want to pick only one record based on certain rules.
May be having data laid out will make my point more clear to you. Here you go :
CREATE TABLE AD_LIST
  FILE_NAME             VARCHAR2(50 BYTE),
  ACTIVITY_START        DATE,
  ACTIVITY_END          DATE,
  DIVISION              VARCHAR2(50 BYTE),
  ITEM_CODE             VARCHAR2(50 BYTE),
  MULT                  NUMBER,
  RETAIL                NUMBER,
  AD_PAGE               VARCHAR2(1 BYTE),
  FORECAST              NUMBER,
  MEMO                  VARCHAR2(50 BYTE)
INSERT INTO AD_LIST VALUES ('FILE_1','01-APR-2010','15-APR-2010','B',1111,5,10,'A',10,'This must be in my result');
INSERT INTO AD_LIST VALUES ('FILE_1','01-APR-2010','15-APR-2010','B',1111,1,1,'B',15,'Must not be in my result');
INSERT INTO AD_LIST VALUES ('FILE_1','01-APR-2010','15-APR-2010','B',1111,6,15,'C',11,'Must not be in my result');
INSERT INTO AD_LIST VALUES ('FILE_1','16-APR-2010','30-APR-2010','N',1111,4,20,'D',40,'Must not be in my result');
INSERT INTO AD_LIST VALUES ('FILE_1','16-APR-2010','30-APR-2010','N',1111,5,15,'E',30,'Must not be in my result');
INSERT INTO AD_LIST VALUES ('FILE_1','16-APR-2010','30-APR-2010','N',1111,1,2,'F',20,'This must be in my result');
CREATE TABLE PAGE_RANK
  AD_PAGE VARCHAR2(1 BYTE),
  RANK NUMBER
INSERT INTO PAGE_RANK VALUES ('A',1);
INSERT INTO PAGE_RANK VALUES ('B',2);
INSERT INTO PAGE_RANK VALUES ('C',3);
INSERT INTO PAGE_RANK VALUES ('D',4);
INSERT INTO PAGE_RANK VALUES ('E',5);
INSERT INTO PAGE_RANK VALUES ('F',6);
COMMIT;
SELECT * FROM AD_LIST
FILE     ACTIVITY     ACTIVITY          ITEM               AD
NAME     START          END          DIV     CODE     MULT     RETAIL     PAGE     FORECAST     MEMO
FILE_1     4/1/2010     4/15/2010     B     1111     5     10     A     10     This must be in my result
FILE_1     4/1/2010     4/15/2010     B     1111     1     1     B     15     Must not be in my result
FILE_1     4/1/2010     4/15/2010     B     1111     6     15     C     11     Must not be in my result
FILE_1     4/16/2010     4/30/2010     N     1111     4     20     D     40     Must not be in my result
FILE_1     4/16/2010     4/30/2010     N     1111     5     15     E     30     Must not be in my result
FILE_1     4/16/2010     4/30/2010     N     1111     1     2     F     20     This must be in my resultNow, from the table AD_LIST I want to group the records based on FILE_NAME, ACTIVITY_START, ACTIVITY_END, DIVISION, ITEM_CODE.
So in my example here we have 2 set of records grouped based on the columns specified.
Also we have one more table, PAGE_RANK, which has a rank corresponding to each ad_page number. Here 1 is higher rank than 2. Hence ad page 'A' takes priority over 'B'. Similarly for all other ad pages.
Now, we need to pick one ad from each group of ads by determining the highest ranked ad page within the group and the value for mult and retail must be replaced with the value that has min(retail/mult). So, using the above data we will have the one having ad page = 'A' and ad page = 'D' as the final results since they have highest ad page rank in their group.
The value for mult and retail values for ad_page 'A' = min (10/5 , 1/1, 15/6) = 1,1(mult,retail).
The value for mult and retail values for ad_page 'D' = min (20/4 , 15/5, 2/1) = 1,2(mult,retail).
Finally I have this query below
SELECT a.file_name,
       a.activity_start,
       a.activity_end,
       a.division,
       a.item_code,
       FIRST_VALUE (a.mult) OVER (PARTITION BY a.file_name, a.activity_start, a.activity_end, a.division, a.item_code ORDER BY (a.retail /
                                                                                                                                a.mult))
                                                                                                    mult,
       FIRST_VALUE (a.retail) OVER (PARTITION BY a.file_name, a.activity_start, a.activity_end, a.division, a.item_code ORDER BY (a.retail /
                                                                                                                                  a.mult))
                                                                                                  retail,
       FIRST_VALUE (a.ad_page) OVER (PARTITION BY a.file_name, a.activity_start, a.activity_end, a.division, a.item_code ORDER BY (b.RANK))
                                                                                                 ad_page,
       a.forecast,
       a.memo                                                                                                
  FROM ad_list a, page_rank b
WHERE a.ad_page = b.ad_pageThis query is giving me all the records but with the values what I wanted in Ad_Page, Mult and Retail columns.
How can I pick only one from each group.
I am getting this FILE     ACTIVITY     ACTIVITY          ITEM               AD
NAME     START          END          DIV     CODE     MULT     RETAIL     PAGE     FORECAST     MEMO
FILE_1     4/1/2010     4/15/2010     B     1111     1     1     A     15     Must not be in my result
FILE_1     4/1/2010     4/15/2010     B     1111     1     1     A     10     This must be in my result
FILE_1     4/1/2010     4/15/2010     B     1111     1     1     A     11     Must not be in my result
FILE_1     4/16/2010     4/30/2010     N     1111     1     2     D     20     This must be in my result
FILE_1     4/16/2010     4/30/2010     N     1111     1     2     D     30     Must not be in my result
FILE_1     4/16/2010     4/30/2010     N     1111     1     2     D     40     Must not be in my resultBut I want this FILE     ACTIVITY     ACTIVITY          ITEM               AD
NAME     START          END          DIV     CODE     MULT     RETAIL     PAGE     FORECAST     MEMO
FILE_1     4/1/2010     4/15/2010     B     1111     1     1     A     10     This must be in my result
FILE_1     4/16/2010     4/30/2010     N     1111     1     2     D     20     This must be in my resultI have to run this query for thousands of such group combination.
Hope some one can throw some light on this query.
Thanks in advance,
Raj.

Frank,
You are marvelous.
That is what I was expecting, but basically I want to display the row with highest page rank which is 'A' and 'D' in this case.
So I have changed my query as below using yours :
WITH mainq AS
     (SELECT a.file_name,
             a.activity_start,
             a.activity_end,
             a.division,
             a.item_code,
             FIRST_VALUE (a.mult) OVER (PARTITION BY a.file_name, a.activity_start, a.activity_end, a.division, a.item_code ORDER BY (a.retail /
                                                                                                                                      a.mult))
                                                                                                    mult,
             FIRST_VALUE (a.retail) OVER (PARTITION BY a.file_name, a.activity_start, a.activity_end, a.division, a.item_code ORDER BY (a.retail /
                                                                                                                                        a.mult))
                                                                                                  retail,
             --FIRST_VALUE (a.ad_page) OVER (PARTITION BY a.file_name, a.activity_start, a.activity_end, a.division, a.item_code ORDER BY (b.RANK))
             a.ad_page,
             a.forecast,
             a.memo,
             ROW_NUMBER () OVER (PARTITION BY a.file_name, a.activity_start, a.activity_end, a.division, a.item_code ORDER BY b.RANK)
                                                                                             AS r_num
        FROM ad_list a, page_rank b
       WHERE a.ad_page = b.ad_page)
SELECT *
  FROM mainq a
WHERE r_num = 1
FILE     ACTIVITY     ACTIVITY          ITEM               AD
NAME     START          END          DIV     CODE     MULT     RETAIL     PAGE     FORECAST     MEMO
FILE_1     4/1/2010     4/15/2010     B     1111     1     1     A     10     This must be in my result
FILE_1     4/16/2010     4/30/2010     N     1111     1     2     D     40     Must not be in my resultMy apologies that I gave you wrong forecast and memo values in my earlier post.
But that is what I wanted and your input greatly helped me to save lot of time by using in one single query.
Earlier I was using cursor to do that and it was not doing any good performance wise.
Thanks to every body for your time and your efforts.
I appreciate it.
Have fun.
~Raj

Similar Messages

  • 1 new update have been added to the project would you like to close the project and apply these updates message in project 2010

    1 new update have been added to the project would you like to close the project and apply these updates message  in project 2010.
    One of the PM is getting above message and not any recent changes happened?

    Hi,
    This message appears when an update has been sent for his approval and is pending. It could happen while opening the project plan, or when clicking on something like "retreive tasks updates" from the backstage menu of MS Project Pro.
    The PM should go to his approval center and check for any approval pending.
    Hope this helps,
    Guillaume Rouyre, MBA, MVP, P-Seller |

  • How to batch download  the elements and flow logic of screen

    hi,all
    i am doing programs transfer without using transport request.
    it is easy to download simple reports,includeing code, text etc.but how can i deal with reports with customed screen.
    for example, i have to download the elements and flow logic of  screen 100 in a report. also, i need to upload in another server.
    i need you help!
    thanks
    Regards
    LT

    Hi,
    There are lots of utilities to do this. just search forum and you will be able to find the one.
    Regards,
    Atish

  • How can i get all the records from three tables(not common records)

    Hi
    I have four base tables at R/3-Side. And i need to extract them from R/3-Side.
    And i dont have any standard extractor for these tables .
    If i create a 'View' on top of these tables. Then it will give only commom records among the three tables.
    But i want all the records from three base tables (not only common).
    So how can i get the all records from three tables. please let me know
    kumar

    You can create separate 3 datasources for three tables and extract data to BW. There you can implement business login to build relation between this data.

  • Is there any way to name the records from a data merge?

    I have a spreadsheet, that has all the names for the images I'm using for a data merge. What I want to do is name the resulting records after the filenames in one of the columns in the spreadsheet. Is there anyway to do this? Or is there some other way to individually name the records from a data merge? I don't have any scripting prowess, so I can't really mess with that. Any help is greatly appreciated! Thanks!

    You merge it along with the others, just like any field. ID cannot do the naming for you during the merge, but most spreadsheets have lots of logic capabilities that should allow you to extract a name for the record from the filename in the column of your choice. The only reason ID knows to find the image instead of writing the filename is that you've used a special name for the field.

  • SQL query to fetch records  from  26 onwards

    Want to know SQL query to fetch records from 26 onwards.

    See the fifth entry on the FAQ page:
    Re: How to attach a java bean in forms6i

  • Picking the records from IT2011.....

    Hi All,
    I am writing the report as per the clients requirement. for this i am using the IT 0007, 2010, 2011. Here i am using the LDB PNP for this report. i have declared  as below.
    INFOTYPES: 0007, 2010,2011.
    The infotypes are filling with the records which are existing in the infotype. Here even old data is also filling in the infotypes that means data other than the selected date from the selection screen.
    To avoide this i have written provide statement as follows.
    provide * from P2011  between pn-begda and pn-endda.
    but i did not get any data from the above statement. My requirement is i need to fetch the records from the IT2011 for the entered date. can anybody tell how to fetch the records from the time infotypes for entered date.
    Thanks & Regards,
    Giri.

    Hi..
    I suggest to use PNPCE LDB and use input as other perion option for selection screen
    and you will get all the recordes valid during the period which you give and the recordes will coming in to the tables 0007, 2010,2011.and just you can read or loop the table.
    TABLES : pernr.
    INFOTYPES: 0001,
               0007,
               2011,
               2010 .
    NODES:  peras.
    TYPES : BEGIN OF ty_final,
           pernr TYPE persno,
           ename  TYPE emnam,
            PBTXT TYPE PBTXT,
            BTRTX TYPE BTRTX,
            END OF ty_final.
    DATA : it_final TYPE TABLE OF ty_final,
           wa_final TYPE ty_final.
    DATA go_table         TYPE REF TO cl_salv_table.
    START-OF-SELECTION.
    GET peras.
      SORT p0001 BY endda DESCENDING.
      READ TABLE p0001 INDEX 1.
      wa_final-pernr = p0001-pernr.
      wa_final-ename  = p0001-ename .
      CALL FUNCTION 'HRWPC_RFC_WERKS_TEXT_GET'
        EXPORTING
          werks      = p0001-werks
        IMPORTING
          werks_text = wa_final-PBTXT.
      CALL FUNCTION 'HRWPC_RFC_BTRTL_TEXT_GET'
        EXPORTING
          werks      = p0001-werks
          btrtl      = p0001-btrtl
        IMPORTING
          btrtl_text = wa_final-BTRTX.
    loop at p2010.
    endloop.
      APPEND wa_final TO it_final.
      CLEAR wa_final.
    END-OF-SELECTION.
      CALL METHOD cl_salv_table=>factory
        IMPORTING
          r_salv_table = go_table
        CHANGING
          t_table      = it_final.
      go_table->display( ).

  • How to fetch all the records from ztable

    Hi 
    My program is outbound program.
    According to the requirement i have to fetch all the records from ztable which are not tranmitted before to the third party and once the records are extracted and written to output file they will be marked as 'X' in the "status" field of that ztable for the next days run.
    How to fetch the records.Please suggest me.
    Thanks,
    Neelima

    HI,
    Fetch all the records whose status is equal to 'X' as whatever data is sent to third party system is marked as 'X' in status field of table after sending.
    You need to first fetch the data into internal table using the select statement where status EQ space. You get the data which is not yet transmitted to third part. And later in the program after trasmitting the data to third party modify the Records in the DB table which are transmitted with Staus eq 'X'.

  • Fetch the records from cache

    say i have emp table
    eno ename sales
    1 david 1100
    2 lara 200
    3 james 1000
    1 david 1200
    2 lara 5400
    4 white 890
    3 james 7500
    1 david 1313
    eno can be duplicate
    when i give empno is 1
    i want to display his sales i.e 1100,1200,1313
    first time i will go to database and fetch the records
    but next time onwards i dont go to database; i will fetch the records from cache;
    i thought doing it using hashmap or hasptable ;both those two don't allow duplicate values(empno has duplicate values);
    How to solve this problem.

    Hi,
    Ever considered splitting that table up. You are thinking about caching thats a
    very good idea. But doesnt it make it vary evident that the table staructure that you have
    keeps a lot of redundant data. Specially it hardly makes a sense to have sales
    figures in a emp table. Instead you can have Emp table containing eno and
    ename with eno as the primary key and have another table called sales with eno
    and sales columns and in this case the eno references the Emp table.
    If you still want to continue with this structure then I think you can go ahead with
    the solution already suggested to you
    Aviroop

  • How to read the records from VO

    hi
    How to read the records from VO and after reading the records the selected records has to be save to DB thru other VO
    help me out

    hi,
    its a custom one i am creating
    Select C.Name, A.Primary_Flag, , B.Comments, B.ATTRIBUTE_CATEGORY, B.ATTRIBUTE1, B.ATTRIBUTE2
    FROM XXVOC_CSD_PRIME_DIAG_CODES_B A, XXVOC_CSD_PRIME_DIAG_CODES_TL B, CSD_DIAGNOSTIC_CODES_TL C, CSD_RO_DIAGNOSTIC_CODES D
    Where A. RO_DIAGNOSTIC_CODE_ID = D. RO_DIAGNOSTIC_CODE_ID
    AND A. RO_DIAGNOSTIC_CODE_ID = B. RO_DIAGNOSTIC_CODE_ID
    AND C.DIAGNOSTIC_CODE = D.DIAGNOSTIC_CODE
    AND A.REPAIR_LINE_ID = :1
    UNION
    SELECT C.NAME, ‘’, ‘’, ‘’,’’,’’
    FROM CSD_DIAGNOSTIC_CODES_TL C, CSD_RO_DIAGNOSTIC_CODES D
    WHERE C.DIAGNOSTIC_CODE = D.DIAGNOSTIC_CODE
    AND D.REPAIR_LINE_ID = :1
    from above query i have to select attributes and set it in the EO based VO
    Edited by: Naveenapps on Feb 22, 2009 10:36 PM

  • How do I delete photo ALBUMS from my iPHONE 4? I sync via icloud and I can not see any folders selected in itunes. I searched the internet and basically there is no one who has the answer to how you delete the iphone photo library and misc albums

    how do I delete photo ALBUMS from my iPHONE 4?
    I sync via icloud and I can not see any folders selected in itunes.
    I searched the internet and basically there is no one who has the answer (so far)
    to how you delete the iphone photo library and misc albums
    I have also had every iphone and I am not stupid.
    charles altman

    Replying to my own post - heh. I downloaded iExplorer (http://www.macroplant.com/iexplorer/) which allowed me access to the files on the phone and there was the phantom movie in the DCIM folder. Deleted it, and all is well - although I still have 0.65gb of Other in iTunes.....

  • I can't change the email on my iCloud account on my iPhone because I can't remember the password, and I can't remember one of the security questions. What do I do?

    I can't change the email on my iCloud account on my iPhone because I can't remember the password, and I can't remember one of the security questions. What do I do?

    Hi karen615,
    Welcome to the Apple Support Communities!
    If you cannot reset your Apple ID password via security questions, you can reset via email authentication. If you are not receiving the email, it may be necessary to contact Apple Support using the link in the Get help section toward the bottom of the article. 
    If you forgot your Apple ID password - Apple Support
    Best regards,
    Joe

  • Is there a way to select all emails at once on the iPad and then delete them at one time?

    Is there a way to select all emails at once on the iPad and then delete them at one time?

    Tap on the edit button at  the top right of the email list. This will let you select the emails to delete, once all are selected, tap on the bottom right button that says delete to delete them all at once.

  • If I'm reading a book on the iPhone and I want to pick up where I left off on my iPad, do I have to search for what page I was on on the iPad or is there a way to sync it?

    If I'm reading a book on the iPhone and I want to pick up where I left off on my iPad, do I have to search for what page I was on on the iPad or is there a way to sync it? Or do I just have to search for a string of text from my iPhone on my iPad?

    On both devices go to Settings>iBooks>Sync Bookmarks>On. Then when you want to quit reading on one device, tap the bookmark in the upper right corner and it will turn red. That marks your place. Close the book on the device now by tapping on the Library button in the upper left corner of the app. That will put the closed book back on the shelf. Tap the home button.
    On the other device, when you tap on the book, it should open to that page. You have to be connected to WiFi in order for this to work. You can read this older discussion for more information. I was involved in that as well.
    https://discussions.apple.com/thread/3754714?start=0&tstart=0

  • Anyone know of a way to adjust the top and side MARGINS of a document printed from iOS numbers? The default margins are too wide. Need more working space.

    Anyone know of a way to adjust the top and side MARGINS of a document printed from iOS numbers? The default margins are too wide. Need more working space.

    Open the document,
    Tap the Tools icon (upper right).
    Tap Document Set up.
    Drag the margins to the position you wish (the actual margin width sould display as you are doing this).

Maybe you are looking for