Query to get a group having n rows each

I have emp table empl_id in sorted order and i need column value "Group no"  based on value of N. (making a group start with 1 having n employees each)
N=2
emp_id    Name   Group No
1001          A            1
1003         B             1
1004         C             2
1006         D             2
1007         E             3
1009         F             3
N=3
emp_id    Name   Group No
1001          A            1
1003         B             1
1004         C             1
1006         D             2
1007         E             2
1009         F             2
Your SQL is highly appricated.

Hi,
Since I don't have a sample version of your table, I'll use scott.emp.
Here's one way:
VARIABLE  n   NUMBER
EXEC     :n := 3;
SELECT    empno, ename
,         CEIL ( ROW_NUMBER () OVER (ORDER BY ename)
               / :n
               )       AS group_no
FROM      scott.emp
ORDER BY  ename
The highest-numbered group may have fewer members than the others.  For example, scott.emp has 14 rows.  There's no way to assign every row to a single group and have 3 members in each group; there is no integer X such that 3 * X = 14.  So the query above assigns 3 members to group_nos 1 through 4, but only assigns 2 rows to group_no=5.

Similar Messages

  • How can I get only the last 2 rows?

    How can I narrow down a query to get only the last two rows in a table ?
    Thanks,
    Mohan

    Thanks a lot Ram for your suggestion but already I have a query which returns a set of rows, of which I would like to further filter and get the last two rows
    <BLOCKQUOTE><font size="1" face="Verdana, Arial">quote:</font><HR>Originally posted by Ramanuj Bangad ([email protected]):
    try out something like this if it helps.
    Example:
    select * from users
    where rownum <= (select count(*) from users)
    minus
    select * from users
    where rownum <= (select count(*) -2 from users )
    <HR></BLOCKQUOTE>
    null

  • Sql query to get distinct count

    Hi
    I use SQL Server Management Studio
    can I have a sql query to get count as shown below against  each month column and name column to get distinct count.
    for example if there is two rows with the same date period and same name then the count should be one in first row and zero in the next row of the same data.
    Table Name: Table1
    Column: Month, Name
    Month
    Name
    Count
    12/1/2012 0:00
    AK
    1
    12/1/2012 0:00
    AK
    0
    12/1/2012 0:00
    AB
    1
    1/1/2013 0:00
    AK
    1
    1/1/2013 0:00
    AK
    0
    1/1/2013 0:00
    AB
    1
    3/1/2013 0:00
    AA
    1
    3/1/2013 0:00
    AK
    1
    3/1/2013 0:00
    AK
    0
    6/1/2013 0:00
    AA
    1
    6/1/2013 0:00
    AK
    1
    6/1/2013 0:00
    AK
    0
    9/1/2013 0:00
    AA
    1
    9/1/2013 0:00
    AK
    1
    9/13/2013 0:00
    AK
    1
    10/1/2013 0:00
    AA
    1
    10/1/2013 0:00
    AK
    1
    10/1/2013 0:00
    AK
    0

    Hi,
    Thanks for the query but this query gives the total count like shown below
    if see the second row in the below table AK for 2012-12-1 gives total count as 2 but need the query to show the first row as 1 and there after 0
    query result
    Month name cnt
    2012-12-01 00:00:00.000 AB 1
    2012-12-01 00:00:00.000 AK 2
    2012-12-01 00:00:00.000 AK 2
    2013-01-01 00:00:00.000 AB 1
    2013-01-01 00:00:00.000 AK 2
    2013-01-01 00:00:00.000 AK 2
    2013-03-01 00:00:00.000 AA 1
    2013-03-01 00:00:00.000 AK 2
    2013-03-01 00:00:00.000 AK 2
    2013-06-01 00:00:00.000 AA 1
    2013-06-01 00:00:00.000 AK 2
    2013-06-01 00:00:00.000 AK 2
    2013-09-01 00:00:00.000 AA 1
    2013-09-01 00:00:00.000 AK 1
    2013-09-13 00:00:00.000 AK 1
    2013-10-01 00:00:00.000 AA 1
    2013-10-01 00:00:00.000 AK 2
    2013-10-01 00:00:00.000 AK 2

  • Need a sql query to get multiple dates in rows

    Hi All,
    i need a query to get dates for last 7 days and each dates should be in one row...
    but select sysdate from dual..gives one row...
    Expexcted Output
    Dates:
    01-oct-2013
    30-sep-2013
    29-sep-2013
    28-sep-2013
    27-sep-2013
    26-sep-2013

    Hi,
    Do you mean that you want all 7 dates together on 1 row?
    Here's one way:
    SELECT LISTAGG ( TO_CHAR ( SYSDATE + 1 - LEVEL
                              , 'DD-Mon-YYYY'
                    ) WITHIN GROUP (ORDER BY LEVEL)    AS txt
    FROM    dual
    CONNECT BY LEVEL <= 7
    This is an example of String Aggregation, that is, taking a column on multiple rows, and concatenating all the values (however many htere happen to be) into 1 big string column 1 row.
    Like everything else, exactly how to do it depends on your Oracle version.
    For more on String Aggregation, including differetn techniques for different versions, see http://www.oracle-base.com/articles/10g/StringAggregationTechniques.php
    Message was edited by: FrankKulash
    Sorry, I mis-read the question.

  • Wrong query is getting generated in WHERE NOT EXISTS  with group by clause

    Query is getting generated wrongly in where not exists section when i use group by function.Please prvoide me any clue to over come the problem.
    /* DETECTION_STRATEGY = NOT_EXISTS */
    INSERT /*+ APPEND */ INTO STG_ETL.I$_DCMT_TIMEZONE_LOOKUP
         TZ_OFFSET,
         ADT_CRT_DT,
         ADT_UPDT_DT,
         IND_UPDATE
    SELECT * FROM (
    SELECT      
         to_number(KOFAX.RECEIVED_TZ)     TZ_OFFSET,
         min(sysdate)     ADT_CRT_DT,
         min(sysdate)     ADT_UPDT_DT,
         'I' IND_UPDATE
    FROM     ESTG.FLAT_FIL_DMS_KOFAX KOFAX
    WHERE     (1=1)
    And (KOFAX.LD_DT = ( select MAX(LD_DT) from ESTG.FLAT_FIL_DMS_KOFAX INNER
    where INNER.ENGAGEMENT=KOFAX.ENGAGEMENT
                   and INNER.KOFAX_FILE_NM = KOFAX.KOFAX_FILE_NM
                   AND INNER.IM_CUST_ID = KOFAX.IM_CUST_ID
              and INNER.BATCH_ID=KOFAX.BATCH_ID)
    AND
    (TO_DATE(KOFAX.LD_DT)>=TO_DATE(SUBSTR('#WAREHOUSE.P_EDW_LAST_RUN',1,10),'YYYY-MM-DD'))
    And (substr(KOFAX.RECEIVED_TZ,1,1) <> '+')
    Group By to_number(KOFAX.RECEIVED_TZ)
    ) S
    WHERE NOT EXISTS (
         SELECT     'X'
         FROM     EDW.DCMT_TIMEZONE_LOOKUP T
         WHERE     T.TZ_OFFSET     = S.TZ_OFFSET AND
         )

    Easiest fix for you would be to change the detection_strategy on the IKM from NOT_EXISTS to either :
    MINUS
    -- Try this out, it should work, it will give the same data through the equiverlant steps.
    NONE
    -- This will load all incoming data into your I$ table, there will be more rows to crunch in the following 'Flag Rows for Update' step, it might give incorrect results potentially - you will have to test it.
    So try MINUS first, failing that, see if NONE gives you what you want in your target.
    Are you inserting only new data or updating existing data?

  • SQL query to find top 5 users having more rows/data in table

    Dear experts,
    OS = HP-UX
    Database = Oracle 9.2.0.8
    AC users = 600
    Ex:-
    select * from all_users where username like 'AC%';
    AC_1
    AC_2
    AC_3
    AC_4
    AC_5
    AC_6
    AC_.
    AC_.
    AC_.
    AC_600
    Each AC user having same tables INCOMING, OUTGOING
    Now i need to find top 5 users having more rows/data in INCOMING , OUTGOING tables. I tried this:
    SQL>conn AC_1/pwd
    select 'select count(*) from '||table_name||';' from user_tables;
    But i get max counts info only for this AC_1 user , however, i need top 5 users having more rows/max counts query.
    Thank you,

    source : oracle forums
    May be , this one.. not tested though.
    Before doing this you need to have select_catalog_role
    WITH tmp
         AS (SELECT owner,
                    table_name,
                    TO_NUMBER (
                       EXTRACTVALUE (
                          xmltype (
                             DBMS_XMLGEN.getxml (
                                'select /*+ PARALLEL*/ count(*) c from '
                                || table_name)),
                          '/ROWSET/ROW/C'))
                       Cnt
               FROM dba_tables
              WHERE 1 = 1 AND table_name IN ('INCOMING', 'OUTGOING')),
         tmp1
         AS (SELECT a.*,
                    MAX (cnt)
                       OVER (PARTITION BY a.table_name ORDER BY a.cnt DESC)
                       maxcnt
               FROM tmp a)
    SELECT DISTINCT a.*
      FROM tmp a, tmp1 b
    WHERE a.cnt = b.maxcnt AND a.table_name = b.table_name;

  • How to modify the query to get the output in a single row

    Hi All,
    Below is the query i have written it works fine
    select DISTINCT right(left(CTACCT,13),4) AS LocationNum,
    tODS_GLBalance.FiscalYearId AS FiscalYearId,
    tODS_GLBalance.FiscalMonthOfYearId AS FiscalMonthOfYearId,
    --tods_GLMetadata.Metric,
    Case when
    tods_GLMetadata.Metric = 'Gross Margin'
    Then SUM(Balance)
    Else 0
    END AS GrossMargin,
    Case when
    tods_GLMetadata.Metric = 'Occupancy'
    Then SUM(Balance)
    Else 0
    END AS Occupancy,
    Case when
    tods_GLMetadata.Metric = 'Payroll Dollars'
    Then SUM(Balance)
    Else 0
    END AS Payroll,
    Case when
    tods_GLMetadata.Metric = 'CF Sales'
    Then SUM(Balance)
    Else 0
    END AS OperatingSales,
    Case when
    tods_GLMetadata.Metric = 'Operations'
    Then SUM(Balance)
    Else 0
    END AS OperatingExpenses
    -- 0 as payroll
    from ods.[JJill].[tODS_GLBalance]
    inner join ods.Staging.tODS_INF_GLPCT ON tODS_GLBalance.PageNum = tODS_INF_GLPCT.CTPAGE
    inner join ods.JJill.tods_GLMetadata ON tods_GLMetadata.AcctDescription = tODS_INF_GLPCT.CTDESC
    where
    (tODS_GLBalance.FiscalYearId = 2012) and
    (tODS_GLBalance.FiscalMonthOfYearId = 2) and
    (right(left(CTACCT,13),4)= 3020)
    group by
    right(left(CTACCT,13),4),
    tODS_GLBalance.FiscalYearId,
    tODS_GLBalance.FiscalMonthOfYearId,
    tods_GLMetadata.Metric
    This is the sample output,
    LocationNum FiscalYearId FiscalMonthOfYearId GrossMargin Occupancy Payroll OperatingSales OperatingExpenses
    3020 2012 2 -112477.00 0.00 0.00 0.00 0.00
    3020 2012 2 0.00 0.00 0.00 -158288.94 0.00
    3020 2012 2 0.00 0.00 0.00 0.00 5625.44
    3020 2012 2 0.00 0.00 24185.79 0.00 0.00
    3020 2012 2 0.00 31075.53 0.00 0.00 0.00
    But, i am expecting the output to be something like this
    LocationNum FiscalYearId FiscalMonthOfYearId GrossMargin Occupancy Payroll OperatingSales OperatingExpenses
    3020 2012 2 -112477.00 31075.53 24185.79 -158288.94 5625.44
    Can someone please help me with changing my query to get the desired output?
    Please let me know if you have any questions.
    Thanks

    Try this:
    SELECT DISTINCT
    RIGHT(LEFT(CTACCT,13),4) AS LocationNum, tODS_GLBalance.FiscalYearId AS FiscalYearId, tODS_GLBalance.FiscalMonthOfYearId AS FiscalMonthOfYearId,
    SUM(CASE WHEN tods_GLMetadata.Metric = 'Gross Margin' THEN Balance ELSE 0 END ) AS GrossMargin,
    SUM(CASE WHEN tods_GLMetadata.Metric = 'Occupancy' THEN Balance ELSE 0 END ) AS Occupancy,
    SUM(CASE WHEN tods_GLMetadata.Metric = 'Payroll Dollars' THEN Balance ELSE 0 END ) AS Payroll,
    SUM(CASE WHEN tods_GLMetadata.Metric = 'CF Sales' THEN Balance ELSE 0 END ) AS OperatingSales,
    SUM(CASE WHEN tods_GLMetadata.Metric = 'Operations' THEN Balance ELSE 0 END ) AS OperatingExpenses
    FROM ods.[JJill].[tODS_GLBalance]
    INNER JOIN ods.Staging.tODS_INF_GLPCT
    ON tODS_GLBalance.PageNum = tODS_INF_GLPCT.CTPAGE
    INNER JOIN ods.JJill.tods_GLMetadata
    ON tods_GLMetadata.AcctDescription = tODS_INF_GLPCT.CTDESC
    WHERE tODS_GLBalance.FiscalYearId = 2012
    AND tODS_GLBalance.FiscalMonthOfYearId = 2
    AND RIGHT(LEFT(CTACCT,13),4) = 3020
    GROUP BY right(left(CTACCT,13),4), tODS_GLBalance.FiscalYearId, tODS_GLBalance.FiscalMonthOfYearId, tods_GLMetadata.Metric

  • SQL Query to get All AD Groups and its users in Active Directory

    Hi,
       Is there any query to get all AD groups and its user in an instance of a SQL server?

    Check this blog.
    http://www.mikefal.net/2011/04/18/monday-scripts-%E2%80%93-xp_logininfo/
    It will give you more than what is required. If you dont want the extra information,then you can try this.. I took the query and removed the bits that you might not require.
    declare @winlogins table
    (acct_name sysname,
    acct_type varchar(10),
    act_priv varchar(10),
    login_name sysname,
    perm_path sysname)
    declare @group sysname
    declare recscan cursor for
    select name from sys.server_principals
    where type = 'G' and name not like 'NT%'
    open recscan
    fetch next from recscan into @group
    while @@FETCH_STATUS = 0
    begin
    insert into @winlogins
    exec xp_logininfo @group,'members'
    fetch next from recscan into @group
    end
    close recscan
    deallocate recscan
    select
    u.name,
    u.type_desc,
    wl.login_name,
    wl.acct_type
    from sys.server_principals u
    inner join @winlogins wl on u.name = wl.perm_path
    where u.type = 'G'
    order by u.name,wl.login_name
    Regards, Ashwin Menon My Blog - http:\\sqllearnings.com

  • How to get query from a record group

    HI
    do we get the query from which record groupis based on in oracle forms with out checking in to the properties.

    Hello,
    No, you cannot get the initial SELECT order from the Record Group.
    Francois

  • SQL or Powershell query to get the SCOM management group id for SCOM 2007 R2 & 2012 / 2012 R2

    Hi All,
    Can any one provide me the SQL or Powershell query to get the SCOM management group id for SCOM 2007 R2 & 2012 / 2012 R2
    I had a SQL query which will query the data from data warehouse and give the management group id but i have lost it for all 3 above.
    Gautam.75801

    Hi Gautam,
    Hope it helps:
    http://blog.tyang.org/2013/03/13/data-aggregation-field-became-empty-in-opsmgr-2007-linked-performance-report/
    http://blog.tyang.org/2012/09/05/mp-authoring-targeting-rms-or-ms/
    Natalya
    ### If my post helped you, please take a moment to Vote as Helpful and\or Mark as an Answer

  • Single row from this query without create a group by

    Can I have a single row from this query without create a group by on tipo (TIPO can have only 2 value (A,D)
    SELECT
    CASE TIPO
    WHEN 'D' THEN SUM(IMPORTO) ELSE 0 END DIMPORTO,
    CASE TIPO
    WHEN 'A' THEN SUM(IMPORTO) ELSE 0 END AIMPORTO
    FROM MGIORNALE
    WHERE K_CONTO = '100001' --CONTO
    AND DECODE(T_MOVIM,'MRAP',TO_DATE('31/12/'||to_char(a_competenza),'DD/MM/YYYY'),DATA_RG)
    -- BETWEEN DATAA AND DATAB
    BETWEEN '01/01/2006' AND '31/12/2006'
    --GROUP BY TIPO
    --AND TIPO = COL_conto
    Thanks in advance

    Is like this?
    sum (CASE TIPO
    WHEN 'D' THEN IMPORTO ELSE 0 END) DIMPORTO,

  • Self join to get related records in one row

    I have a table that has individual records for each family member.
    tPerson.LastName, tPerson.FirstName, tPerson.RelationshipCode, tPerson.FamilyUnitCode, tPerson.JobCode
    Smith, John,HD, 1234, AD
    Smith, Jill, SP, 1234, TC
    Olson, Fred, HD, 2345, AV
    Olson, Wilma, SP, 2345, MD
    Adams, Nate, HD, 3456, DP
    Adams, Heidi, SP, 3456, DP
    Franks, John, HD, 4567, AV
    Williams, Pauline, HD, 5678, TC
    I need to get each family unit in one row, preferably without a group on, for a report because I need to compare the jobcodes of HD and SP to decide how to build an expression for a listing. I need to also get singles with no spouse info.
    FamilyCode, Lastname, HDFirstName, SPFirstName, HDJobCode, SPJobCode
    1234, Smith, John, Jill, AD, TC
    2345, Olson, Fred, Wilma, AV, MD
    3456, Adams, Nate, Heidi, DP, DP
    4567, Franks, John, NULL, AV, NULL
    5678, Williams, Pauline, NULL, TC, NULL
    Does the type on constraint affect the effect of an inner join? I have trouble getting the left side returning rows where there is no SP records for that familyCode.
    Any help? John

    >> I have a table that has individual records [sic] for each family member. <<
    Rows are not records. And you posted no DDL.
    Please follow basic Netiquette and post the DDL we need to answer this. Follow industry and ANSI/ISO standards in your data. You should follow ISO-11179 rules for naming data elements. You should follow ISO-8601 rules for displaying
    temporal data. We need to know the data types, keys and constraints on the table. Avoid dialect in favor of ANSI/ISO Standard SQL. And you need to read and download the PDF for:
    https://www.simple-talk.com/books/sql-books/119-sql-code-smells/
    The sample data looks like it has a tibble on it. This is the classic design error of putting meta data, like a “t-” on tables and data element names. The next classic error you made
    is a table name that is singular and vague; do you really have only one “Person” in a table? According to ISO-11179 rules, that is what you said.
    >> I need to get each family unit in one row, ..<<
    Not in RDBMS. Please look up the term “1NF” or “First Normal Form” which forbids structure data in columns.
    But it just gets worse. Being in a family is a relationship, so it has its own table. The individuals are entities, so they have a table. Having a job is another relationship, so it is
    in a third table. In your world, all these things are crammed into a single table! This might be how an OO programmer would attempt to do RDBMS that first time, but it is not good. Here is skeleton to get your started: 
    CREATE TABLE Personnel
    (emp_id CHAR(9) NOT NULL PRIMARY KEY,
    last_name VARCHAR(20) NOT NULL,
    first_name VARCHAR(20) NOT NULL);
    CREATE TABLE Family_Units
    (family_unit CHAR(4) NOT NULL,
    relationship_code CHAR(5) NOT NULL
    CHECK (relationship_code IN ('spouse', ????)),
    PRIMARY KEY (family_unit, relationship_code),
    emp_id_1 CHAR(9) NOT NULL
    REFERENCES Personnel
    ON DELETE CASCADE,
    emp_id_2 CHAR(9) NOT NULL
    REFERENCES Personnel
    ON DELETE CASCADE,
    CHECK (emp_id_1 <> emp_id_2)
    CREATE TABLE Employment
    (emp_id_1 CHAR(9) NOT NULL
    REFERENCES Personnel
    ON DELETE CASCADE PRIMARY KEY,
    job_code CHAR(2) NOT NULL); -- do you know about DOT codes?
    See how we use DRI actions? Etc. 
    >> I need to compare the job_codes of HD and SP to decide how to build an expression [sic] for a listing. I need to also get singles with no spouse info. <<
    Expression return scalar values in SQL. You meant query. Where is the SQL you attempted? Is “spouse” the only relationship? 
    You have not posted enough information for anyone to really help you. What little we can extract from this says that you have no idea how about RDBMS. Want to do some reading, follow
    Netiquette and try again? 
    --CELKO-- Books in Celko Series for Morgan-Kaufmann Publishing: Analytics and OLAP in SQL / Data and Databases: Concepts in Practice Data / Measurements and Standards in SQL SQL for Smarties / SQL Programming Style / SQL Puzzles and Answers / Thinking
    in Sets / Trees and Hierarchies in SQL

  • Need help in optimizing the query with joins and group by clause

    I am having problem in executing the query below.. it is taking lot of time. To simplify, I have added the two tables FILE_STATUS = stores the file load details and COMM table that is actual business commission table showing records successfully processed and which records were transmitted to other system. Records with status = T is trasnmitted to other system and traansactions with P is pending.
    CREATE TABLE FILE_STATUS
    (FILE_ID VARCHAR2(14),
    FILE_NAME VARCHAR2(20),
    CARR_CD VARCHAR2(5),
    TOT_REC NUMBER,
    TOT_SUCC NUMBER);
    CREATE TABLE COMM
    (SRC_FILE_ID VARCHAR2(14),
    REC_ID NUMBER,
    STATUS CHAR(1));
    INSERT INTO FILE_STATUS VALUES ('12345678', 'CM_LIBM.TXT', 'LIBM', 5, 4);
    INSERT INTO FILE_STATUS VALUES ('12345679', 'CM_HIPNT.TXT', 'HIPNT', 4, 0);
    INSERT INTO COMM VALUES ('12345678', 1, 'T');
    INSERT INTO COMM VALUES ('12345678', 3, 'T');
    INSERT INTO COMM VALUES ('12345678', 4, 'P');
    INSERT INTO COMM VALUES ('12345678', 5, 'P');
    COMMIT;Here is the query that I wrote to give me the details of the file that has been loaded into the system. It reads the file status and commission table to show file name, total records loaded, total records successfully loaded to the commission table and number of records that has been finally transmitted (status=T) to other systems.
    SELECT
        FS.CARR_CD
        ,FS.FILE_NAME
        ,FS.FILE_ID
        ,FS.TOT_REC
        ,FS.TOT_SUCC
        ,NVL(C.TOT_TRANS, 0) TOT_TRANS
    FROM FILE_STATUS FS
    LEFT JOIN
        SELECT SRC_FILE_ID, COUNT(*) TOT_TRANS
        FROM COMM
        WHERE STATUS = 'T'
        GROUP BY SRC_FILE_ID
    ) C ON C.SRC_FILE_ID = FS.FILE_ID
    WHERE FILE_ID = '12345678';In production this query has more joins and is taking lot of time to process.. the main culprit for me is the join on COMM table to get the count of number of transactions transmitted. Please can you give me tips to optimize this query to get results faster? Do I need to remove group and use partition or something else. Please help!

    I get 2 rows if I use my query with your new criteria. Did you commit the record if you are using a second connection to query? Did you remove the criteria for file_id?
    select carr_cd, file_name, file_id, tot_rec, tot_succ, tot_trans
      from (select fs.carr_cd,
                   fs.file_name,
                   fs.file_id,
                   fs.tot_rec,
                   fs.tot_succ,
                   count(case
                            when c.status = 'T' then
                             1
                            else
                             null
                          end) over(partition by c.src_file_id) tot_trans,
                   row_number() over(partition by c.src_file_id order by null) rn
              from file_status fs
              left join comm c
                on c.src_file_id = fs.file_id
             where carr_cd = 'LIBM')
    where rn = 1;
    CARR_CD FILE_NAME            FILE_ID           TOT_REC   TOT_SUCC  TOT_TRANS
    LIBM    CM_LIBM.TXT          12345678                5          4          2
    LIBM    CM_LIBM.TXT          12345677               10          0          0Using RANK can potentially produce multiple rows to be returned though your data may prevent this. ROW_NUMBER will always prevent duplicates. The ordering of the analytical function is irrelevant in your query if you use ROW_NUMBER. You can remove the outermost query and inspect the data returned by the inner query;
    select fs.carr_cd,
           fs.file_name,
           fs.file_id,
           fs.tot_rec,
           fs.tot_succ,
           count(case
                    when c.status = 'T' then
                     1
                    else
                     null
                  end) over(partition by c.src_file_id) tot_trans,
           row_number() over(partition by c.src_file_id order by null) rn
    from file_status fs
    left join comm c
    on c.src_file_id = fs.file_id
    where carr_cd = 'LIBM';
    CARR_CD FILE_NAME            FILE_ID           TOT_REC   TOT_SUCC  TOT_TRANS         RN
    LIBM    CM_LIBM.TXT          12345678                5          4          2          1
    LIBM    CM_LIBM.TXT          12345678                5          4          2          2
    LIBM    CM_LIBM.TXT          12345678                5          4          2          3
    LIBM    CM_LIBM.TXT          12345678                5          4          2          4
    LIBM    CM_LIBM.TXT          12345677               10          0          0          1

  • Groups having non-overlapping intervals

    Hi there,
    I need help on some mind boggling overlap problem, or perhaps non-overlap problem.
    Having the sample data below, I need to put together subcodes in groups having non-overlapping
    intervals [MIN_VAL;MAX_VAL[
    I have this table:
    SQL>create table t (product   varchar2(1) not null
      2                 ,subcode   number(1)   not null, constraint subcode_chk check (subcode >= 0)
      3                 ,min_val   number(2)   not null, constraint min_val_chk check (min_val >= 0)
      4                 ,max_val   number(2)   not null, constraint max_val_chk check (max_val >= 0)
      5                 ,constraint t_pk primary key (product, subcode)
      6                 ,constraint t_val_chk check (min_val < max_val));
    Table created.
    SQL>
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 0, 0, 99);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 1, 0, 99);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 2, 18, 67);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 3, 20, 65);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 4, 0, 99);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 5, 45, 60);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 6, 20, 40);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 7, 0, 99);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 8, 60, 65);
    1 row created.
    SQL>insert into t (product, subcode, min_val, max_val) values ('A', 9, 0, 99);
    1 row created.
    SQL>commit
      2  /
    Commit complete.
    SQL>
    SQL>  select product, subcode, min_val, max_val
      2      from t
      3     where product = 'A'
      4  order by product, subcode;
    PRODUCT    SUBCODE    MIN_VAL    MAX_VAL
    A                0          0         99
    A                1          0         99
    A                2         18         67
    A                3         20         65
    A                4          0         99
    A                5         45         60
    A                6         20         40
    A                7          0         99
    A                8         60         65
    A                9          0         99
    10 rows selected.
    SQL>The records of interest are subcodes 5,6,8 since they in certain cases can be considered as one subcode.
    It is OK, that MAX_VAL of one record = MIN_VAL of other record. The main thing is that the subcodes
    within a group are mutual disclosing on MIN_VAL, MAX_VAL.
    SQL>  select product, subcode, min_val, max_val
      2      from t
      3     where product = 'A'
      4       and subcode in (5,6,8)
      5  order by min_val;
    PRODUCT    SUBCODE    MIN_VAL    MAX_VAL
    A                6         20         40
    A                5         45         60
    A                8         60         65
    SQL>I have started out by trying to solve it using lag/lead analytical functions, but without luck.
    Next, I've come up with this hierarchial query, but I don't quite understand it myself, and that bothers me!
    SQL>    select distinct -- This, distinct, bothers me!
      2                      product
      3                     ,subcode
      4                     ,min_val
      5                     ,max_val
      6  --                   ,connect_by_isleaf
      7  --                   ,connect_by_root subcode
      8        from t
      9       where connect_by_isleaf = 1 -- Why does this help me?
    10  start with -- This, start with, seems "clumpsy"
    11            min_val in (  select min_val
    12                            from t
    13                        group by product, subcode, min_val)
    14  connect by nocycle -- This, nocycle, really bothers me!
    15                     min_val > prior min_val
    16                 and max_val <= prior max_val
    17                 and product = prior product
    18                 and subcode <> prior subcode
    19    order by product
    20            ,subcode
    21            ,min_val
    22            ,max_val;
    PRODUCT    SUBCODE    MIN_VAL    MAX_VAL
    A                5         45         60
    A                6         20         40
    A                8         60         65
    SQL>Currently I'm struggling with just identifying the three subcodes. In the perfect world this would be better output
    PRODUCT    SUBCODE    MIN_VAL    MAX_VAL   GROUP_FLAG
    A                0          0         99
    A                1          0         99
    A                2         18         67
    A                3         20         65
    A                4          0         99
    A                5         45         60            1
    A                6         20         40            1
    A                7          0         99
    A                8         60         65            1
    A                9          0         99Or even better, if using herarchial query:
    PRODUCT    SUBCODE    MIN_VAL    MAX_VAL   ROOT_SUBCODE
    A                0          0         99              0
    A                1          0         99              1
    A                2         18         67              2
    A                3         20         65              3
    A                4          0         99              4
    A                5         45         60              6
    A                6         20         40              6
    A                7          0         99              7
    A                8         60         65              6
    A                9          0         99              9Any help and inspiration would be much appreciated. But please don't get offended if I don't follow up the next 12-14 hrs.
    Regards
    Peter
    BANNER
    Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64biEdited by: Peter on May 19, 2009 12:52 PM
    - Changed line 15 in hierarchial query

    Brillant as always, Frank. Ten points and mange tak for you.
    (1) What is your concept of "group" in this problem? In what sense do subcodes 5, 6 and 8 form a group? Is it that they share the quality of not overlapping with some other row with the same product? That is, will there be at most two groups per product: rows that overlap with every other row, and rows that don't?By group I mean, that when isolated from other subcodes, a group does not overlap. For product A, I have 10 different subcodes. In certain situations I'm allowed to consider 5,6 and 8 as one, since they don't overlap. In general the data presented results in 8 groups, 7 groups having 1 subcode, 1 group having 3 subcodes.
    (2) What you mean by "mutually disclosing"? Is it that the min_val to max_val ranges do not overlap?Yes. They are however allowed to be equal.
    As to your query. Seems you're right, it might actually be that "simple". I changed slightly, allowing >= and <=
    SQL> SELECT m.*,
      2         CASE
      3            WHEN
      4            EXISTS (
      5                     SELECT  NULL
      6                     FROM    t
      7                     WHERE   product = m.product
      8                     AND     (       min_val >= m.max_val
      9                             OR      max_val <= m.min_val
    10                             )
    11                   )
    12         THEN 1 END group_flag
    13    FROM t m;
    PRODUCT    SUBCODE    MIN_VAL    MAX_VAL GROUP_FLAG
    A                0          0         99
    A                1          0         99
    A                2         18         67
    A                3         20         65
    A                4          0         99
    A                5         45         60          1
    A                6         20         40          1
    A                7          0         99
    A                8         60         65          1
    A                9          0         99
    10 rows selected.
    SQL>
    This assumes that min_val <= max_val on each row.Your assumption is perfectly correct, as expessed in check constraint on table t.
    >
    The rest of this message concerns the CONNECT BY query you posted, in case you want to understand it better.
    When I run the CONNECT BY query you posted, I get these results:
    P    SUBCODE    MIN_VAL    MAX_VAL
    A          0          0         99
    A          1          0         99
    A          4          0         99
    A          5         45         60
    A          6         20         40
    A          7          0         99
    A          8         60         65
    A          9          0         99
    Ouch, my bad. Somehow I posted the wrong query. I have edited line 15 from
      15                    min_val >= prior min_valinto
      15                    min_val > prior min_val
    The START WITH clause includes all rows: you might as well not have a START WITH clause:
    10  start with -- This, start with, seems "clumpsy"
    11            min_val in (  select min_val
    12                            from t
    13                        group by product, subcode, min_val)
    That's great, somehow I was misled to believe that wew should always have a START WITH.
    Thank you for your remainding comments on hierarchial query. I'll definitely have to play around with it to fully understand. With the edit mentioned, and
    without a START WITH it now looks as,
    SQL>  select distinct -- This, distinct, bothers me!
      2                       product
      3                      ,subcode
      4                      ,min_val
      5                      ,max_val
      6         from t
      7        where connect_by_isleaf = 1 -- Why does this help me?
      8   connect by nocycle -- This, nocycle, really bothers me!
      9                      min_val > prior min_val
    10                  and max_val <= prior max_val
    11                  and product = prior product
    12                  and subcode <> prior subcode  -- Not necessary
    13     order by product
    14             ,subcode
    15             ,min_val
    16             ,max_val;
    PRODUCT    SUBCODE    MIN_VAL    MAX_VAL
    A                5         45         60
    A                6         20         40
    A                8         60         65
    3 rows selected.
    SQL>One final question. In your solution with EXISTS, you use < and >. In my rewritten example I use <= and >=. It seems that it still works, even without a condition on subcode != m.subcode in the subquery.
    Maybe I'm too tired by now, but why is that? - just don't get it
    Regards
    Peter

  • Query to get total counts in the given scenario

    Hi,
    I am using Oracle 10g
    I have a table A with following data
    AgId     Trm     CD     S
    1000     100010     12-JAN     A
    1000     100019     20-MAR     A
    1000     100019     20-JUL     D
    1001     100011     25-JAN     A
    1001     100011     20-FEB     D
    1001     100011     23-MAR     A
    1001     100012     31-JAN     A
    1002     100013     14-FEB     A
    1002     100013     05-APR     D
    1002     100015     02-MAY     A
    1003     100014     03-MAR     A
    1003     100014     25-MAR     D
    1004     100016     22-MAY     A
    1004     100017     21-JUN     A
    1004     100018     01-JUL     A
    1005     100020     21-MAY     D
    1005     100020     21-JUL     A
    1005     100020     11-AUG     D
    Here the overall status of AgId '1000' is A as he is having atleast 1 Trm active
    Similarly, status of AgId '1001' is A
    status of AgId '1002' is A
    But,status of AgId '1003' is D as his trm is disconnected after activation(according to date column'CD')
    Then, status of AgId '1004' is A
    and finally status of AgId '1005' is D again as his trm deactivated, activated and deactivated at last
    So, considering these criteria can any one give me a query to get total no of AgId's who are 'Active' and similarly for 'Deactive'

    Hi,
    when you put some code please enclose it between two lines starting with {noformat}{noformat}
    i.e.:
    {noformat}{noformat}
    CREATE TABLE ... etc.
    {noformat}{noformat}
    Also do not forget to put correct statements. Your insert were missing semicolon at the end.
    Coming back to your problem, I assum that the current status of any trm is the latest status so I have done what follows:
    {code:sql}
    SELECT agid
         , trm
         , cd
         , s
         , ROW_NUMBER () OVER (PARTITION BY agid, trm ORDER BY cd) rn
         , COUNT (*) OVER (PARTITION BY agid, trm) rn_tot
    FROM a
    ORDER BY agid, trm, cd;
    Output:
          AGID        TRM CD        S         RN     RN_TOT
          1000     100010 12-JAN-12 A          1          1
          1000     100019 20-MAR-12 A          1          2
          1000     100019 20-JUL-12 D          2          2
          1001     100011 25-JAN-12 A          1          3
          1001     100011 20-FEB-12 D          2          3
          1001     100011 23-MAR-12 A          3          3
          1001     100012 31-JAN-12 A          1          1
          1002     100013 14-FEB-12 A          1          2
          1002     100013 05-APR-12 D          2          2
          1002     100015 02-MAY-12 A          1          1
          1003     100014 03-MAR-12 A          1          2
          1003     100014 25-MAR-12 D          2          2
          1004     100016 22-MAY-12 A          1          1
          1004     100017 21-JUN-12 A          1          1
          1004     100018 01-JUL-12 A          1          1
          1005     100020 21-MAY-12 D          1          3
          1005     100020 21-JUL-12 A          2          3
          1005     100020 11-AUG-12 D          3          3I have used to columns rn and rn_tot to find the latest entry for a specific agid, trm
    Using the query above I have done the following:
    WITH mydata AS
       SELECT agid
            , trm
            , cd
            , s
            , ROW_NUMBER () OVER (PARTITION BY agid, trm ORDER BY cd) rn
            , COUNT (*) OVER (PARTITION BY agid, trm) rn_tot
        FROM a
    SELECT agid
         , CASE WHEN SUM (CASE s WHEN 'A' THEN 1 END) > 0 THEN 'A' ELSE 'D' END s
      FROM mydata
    WHERE rn = rn_tot
    GROUP BY agid;
    Output:
          AGID S
          1000 A
          1001 A
          1002 A
          1003 D
          1004 A
          1005 D
    {code}
    Which is listing the agid and its status if at least there is one trm with final status 'A' for that agid.
    To sum up everything you can do simply like this:
    {code:sql}
    WITH mydata AS
       SELECT agid
            , trm
            , cd
            , s
            , ROW_NUMBER () OVER (PARTITION BY agid, trm ORDER BY cd) rn
            , COUNT (*) OVER (PARTITION BY agid, trm) rn_tot
        FROM a
    totdata AS
       SELECT agid
            , CASE WHEN SUM (CASE s WHEN 'A' THEN 1 END) > 0 THEN 'A' ELSE 'D' END s
         FROM mydata
        WHERE rn = rn_tot
        GROUP BY agid
    SELECT S, COUNT(*) cnt
      FROM totdata
    GROUP BY S;
    Output:
    S        CNT
    D          2
    A          4
    {code}
    Regards.
    Al                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   

Maybe you are looking for