Home > other >  Create rows in Oracle SQL - Complex
Create rows in Oracle SQL - Complex

Time:10-06

I have a table MEASURES

M_ID MBK_NAME MCP_NAME
10 null MCCP
11 MCCP LOOPS

I want to run a SQL to get the following output

10 MCCP
11 MCCP01
11 LOOP
11 LOOP01

So 2 rows in the table need to become 4 Some indicated an inline view might help

In case you want to try :

CREATE TABLE MEASURES
("M_ID" NUMBER(10,0), 
 "MBK_NAME" VARCHAR2(100 BYTE),
 "MCP_NAME" VARCHAR2(100 BYTE));

Insert into MEASURES (M_ID,MBK_NAME,MCP_NAME) values (10,null,'MCCP');
Insert into MEASURES (M_ID,MBK_NAME,MCP_NAME) values (11,'MCCP','LOOPS');
commit;

UPDATED TO ADD LOGIC as Requested thanks @JR and @DR great. There are more cols in the table m_id, mbk_name and mcp_name are one with logic.

Logic

  • Find distinct mbk_names / mcp_names where length >=4 chars
  • For each - find the associated 2 latest records in MEASURES (by m_id)
  • where there than 2 or more rec take first 2 based on m_id. Output should be that m_id
  • where there is only 1 use same id for both and create ABCD and ABCD01 records

Other permuatations for input are

-1-
M_ID   MBK_NAME   MCP_NAME
51     JDKJPP     JDKJPP
57     JDKJPP     JDKJPP
61     JDKJPP     JDKJPP

OUT
51 JDKJ JDKJPP JDKJPP
57 JDKJ01 JDKJPP JDKJPP

-2-
M_ID MBK_NAME MCP_NAME
101 HTTPKHN_GT HTTPKHN_GT

OUT
101 HTTP HTTPKHN_GT HTTPKHN_GT
101 HTTP01 HTTPKHN_GT HTTPKHN_GT

-3-
M_ID MBK_NAME MCP_NAME
15 PIPSTT KOOLXX 25 PIPSTT KOOLXX

OUT
15 PIPS PIPSTT KOOLXX
25 PIPS01 PIPSTT KOOLXX
15 KOOL PIPSTT KOOLXX
25 KOOL01 PIPSTT KOOLXX

Data for Above examples

-- Test 1
TRUNCATE TABLE MEASURES;
Insert into MEASURES (M_ID,MBK_NAME,MCP_NAME) values 
(51,'JDKJPP','JDKJPP');
Insert into MEASURES (M_ID,MBK_NAME,MCP_NAME) values 
(57,'JDKJPP','JDKJPP');
Insert into MEASURES (M_ID,MBK_NAME,MCP_NAME) values 
(61,'JDKJPP','JDKJPP');
commit;

-- Test 2
TRUNCATE TABLE MEASURES;  
Insert into MEASURES (M_ID,MBK_NAME,MCP_NAME) values 
(101,'HTTPKHN_GT','HTTPKHN_GT');  
commit;

-- Test 3
TRUNCATE TABLE MEASURES;
Insert into MEASURES (M_ID,MBK_NAME,MCP_NAME) values 
(15,'PIPSTT','KOOLXX');
Insert into MEASURES (M_ID,MBK_NAME,MCP_NAME) values   
(25,'PIPSTT','KOOLXX');
commit;

CodePudding user response:

MBK_NAME appears to be irrelevant.

Create a table with two rows, containing the text '' and '01'.

JOIN against that table. The Cartesian cross product will give you the desired four rows.


You mentioned (11, MCCP01), but I think you meant (10, MCCP01).

CodePudding user response:

There is no explanation behind the desired output. Like something about why 4 rows and what is the basic logic, is the data structure maybe tree-like, what about orderings, joins... As just something that will give the result, without knowing anything of the above mentioned explanations (and without taking them in consideration) here is the code...

SELECT DISTINCT
    LEVEL "LVL",
    M_ID "M_ID",
    CASE LEVEL 
        WHEN 1 THEN  COALESCE(MBK_NAME, MBK_NAME_2, MBK_NAME_3, MBK_NAME_4) 
        WHEN 2 THEN  COALESCE(MBK_NAME_2, MBK_NAME_3, MBK_NAME_4)
        WHEN 3 THEN  COALESCE(MBK_NAME_3, MBK_NAME_4)
        WHEN 4 THEN  MBK_NAME_4
    END "NAMES"
FROM
    (
        SELECT
            a.M_ID "M_ID",
            CASE WHEN FIRST_VALUE(a.MBK_NAME) OVER(PARTITION BY 1 ORDER BY 1 ROWS BETWEEN 1 PRECEDING And CURRENT ROW) Is Not Null THEN a.MBK_NAME END "MBK_NAME", 
            CASE WHEN a.MBK_NAME Is Not Null THEN a.MBK_NAME || LPAD(ROWNUM - 1, 2, '0') END "MBK_NAME_2",
            COALESCE (SubStr(a.MCP_NAME, 1, 4), SubStr(a.MBK_NAME, 1, 4)) "MBK_NAME_3",
            CASE WHEN a.MBK_NAME Is Not Null THEN COALESCE (SubStr(a.MCP_NAME, 1, 4), SubStr(a.MBK_NAME, 1, 4)) || LPAD(ROWNUM - 1, 2, '0') END "MBK_NAME_4"
        FROM
            MEASURES a
        ORDER BY
            a.M_ID
    )
WHERE (LEVEL = 1 And CASE WHEN MBK_NAME_2 Is Null THEN 'Y' ELSE 'N' END = 'Y') OR 
      ( LEVEL <> 1 And CASE WHEN MBK_NAME_2 Is Null THEN 'Y' ELSE 'N' END = 'N')
CONNECT BY LEVEL <= 4
ORDER BY LEVEL, M_ID

...resulting as

LVL M_ID NAMES
1 10 MCCP
2 11 MCCP01
3 11 LOOP
4 11 LOOP01
  • Related