2016-12-14 61 views
0

我正在查询有关某些值的分组并将数据插入基于分组的不同表中。在Oracle中查找分组记录

表名是DETAILS2。该表是这样的:

NUM2 MAT_NUM  TRAVEL_DT  TRAVEL_TYP  TRAVEL_REQ 

1-7OR Rail  11-OCT-2016  Train   2 

1-7OR Ground  12-OCT-2016  Bus   2 

1-7OR Fly   15-0CT-2016  Flight   1 

1-72R Rail  11-SEP-2016  Train   2 

1-72R Ground  12-SEP-2016  Bus   3 

1-72R Fly   15-SEP-2016  Flight   1 

我需要通过NUM2,MAT_NUM第一组,然后由TRAVEL_REQ。

  1. 如果我发现MAT_NUM是Rail或Ground与TRAVEL_REQ相同,那么我只需要在另一个表中插入一条记录。
  2. 如果我发现MAT_NUM是铁路或地面与不同的TRAVEL_REQ,那么我需要插入两个记录到另一个表。
  3. 如果我发现MAT_NUM是Fly,那么我只需要在另一个表中插入一条记录。

为了达到这个目的,我先写了下面的代码。但它插入所有记录。你能帮我修改代码吗?

DECLARE 

    NUM1 VARCHAR2(50); 
    NXTNUM1 VARCHAR2(50); 
    DECIDER VARCHAR2(10); 
    TYP1 VARCHAR2(50); 

    CURSOR FET_TYP 
    IS 
    SELECT DISTINCT NUM2, 
      LEAD(NUM2) OVER (ORDER BY NUM2), 
      CASE WHEN DET.MAT_NUM NOT LIKE '%Fly%' THEN 0 ELSE 1 END DECIDER, 
      MAT_NUM 
    FROM DETAILS2 
    ORDER BY NUM2; 

    BEGIN 
    OPEN FET_TYP; 
    LOOP 

    FETCH FET_TYP 
    INTO NUM1, 
      NXTNUM1, 
      DECIDER, 
      TYP1; 

    EXIT WHEN FET_TYP%NOTFOUND; 

    IF ((NUM1 = NXTNUM1) AND (DECIDER = 0)) 
    THEN 

    INSERT INTO TEMP1 
    VALUES (NUM1, TYP1, 'Ground'); 

    ELSIF ((NUM1 = NXTNUM1) AND (DECIDER = 1)) 
    THEN 

    INSERT INTO TEMP1 
    VALUES (NUM1, TYP1, 'Flight'); 

    END IF; 

    END LOOP; 

    COMMIT; 

    CLOSE FET_TYP; 

    END; 

以下是最终输出的样子。

NUM2 MAT_NUM  TRAVEL_DT  TRAVEL_TYP  TRAVEL_REQ 

1-7OR Ground  12-OCT-2016  Bus   2 

1-7OR Fly   15-0CT-2016  Flight   1 

1-72R Rail  11-SEP-2016  Train   2 

1-72R Ground  12-SEP-2016  Bus   3 

1-72R Fly   15-SEP-2016  Flight   1 

这些都是与在写入插入语句我会插入一些默认值沿着主列输出。第一条记录可以是铁路或地面。 TRAVEL_REQ具有相同的值时无关紧要。

+0

这可能没有游标可行。你能在TEMP1中编辑你的文章和预期的结果吗? – Anand

+2

在你的第一个条件(1.) - 应该插入哪条记录?只说“只有一个”是不够的,你必须说明哪一个。然后:在“其他表”中插入什么 - 这个表中的行是否有相同的列?还是只有一些列?或者完全不同的东西?另一个问题:条件(3.)是什么意思?对于1-70R你有三种类型。其中之一是FLY。这是否意味着你只在三行中插入一行?如果是这样,哪一个? (如果travel_req在另外两行中不同 - 这将与条件2相矛盾。) – mathguy

+0

1.任何人都可以插入。 2.对于1-7OR,我插入2条记录,因为TRAVEL_REQ是相同的。对于1-72R,我插入3条记录,因为TRAVEL_REQ对于所有 –

回答

1

您可以简单地根据您的条件使用row_number函数。

select num2,mat_num,travel_dt,travel_typ,travel_req 
from (select d.* 
     ,row_number() over(partition by num2,travel_req order by travel_req,mat_num) rn 
     from details2 d 
    ) x 
where rn = 1 

使用返回结果集insert所需的列到不同的表。

+0

不同,所以您好vkp,谢谢您的回答。我的一位同事也提出了这个问题。但是,如果我们使用这个,那么MAT_NUM上的条件将被忽略,并且结果集对于'1-72R'记录将是不同的,因为我们只是通过NUM2进行分区而不是MAT_NUM –

+0

我做了一个UNION ALL,并且工作完美。非常感谢vkp! select select num2,mat_num,travel_dt,travel_typ,travel_req from(select d。* ,ROW_NUMBER()在从details2 d )(由NUM2分区,travel_req为了通过travel_req,mat_num其中MAT_NUM不喜欢“%粉煤灰%)RN X 其中RN = 1 UNION ALL 选择NUM2,mat_num,travel_dt ,travel_typ,travel_req 从(选择d * ,ROW_NUMBER()以上(分区由NUM2,通过travel_req travel_req顺序,mat_num其中LIKE“%粉煤灰%)RN 从details2 d mAT_NUM)× 其中RN = 1 –