【问题标题】:Finding grouped records in Oracle在 Oracle 中查找分组记录
【发布时间】:2016-12-14 17:57:13
【问题描述】:

我正在查询有关某些值的分组并根据分组将数据插入到不同的表中。

表名是 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 是具有相同 TRAVEL_REQ 的 Rail 或 Ground,那么我只需将一条记录插入到另一个表中。
  2. 如果我发现 MAT_NUM 是具有不同 TRAVEL_REQ 的 Rail 或 Ground,那么我需要将两条记录插入到另一个表中。
  3. 如果我发现 MAT_NUM 是 Fl​​y,那么我只需将一条记录插入到另一个表中。

为了实现这一点,我先写了如下代码。但它正在插入所有记录。你能帮我修改一下代码吗?

    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 具有相同的值时无关紧要。

【问题讨论】:

  • 这在没有游标的情况下可能是可行的。您可以在 TEMP1 中编辑您的帖子并获得预期结果吗?
  • 在您的第一个条件 (1.) - 应该插入哪个记录?光说“只有一个”是不够的,你必须说明是哪一个。然后:在“其他表”中插入了什么 - 来自该表的行,具有相同的列?还是只有一些列?还是完全不同的东西?另一个问题:条件(3.)是什么意思?对于 1-70R,您拥有所有三种类型。其中之一是 FLY。这是否意味着您在所有三行中只插入一行?如果是这样,是哪一个? (如果 travel_req 在其他两行中不同怎么办 - 这将与条件 2 相矛盾。)
  • 1.任何人都可以插入。 2. 对于 1-7OR ,我插入 2 条记录,因为 TRAVEL_REQ 是相同的。对于 1-72R,我插入 3 条记录,因为 TRAVEL_REQ 对所有人都不同

标签: sql oracle plsql


【解决方案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 所需的列添加到不同的表中。

【讨论】:

  • 嗨 vkp,谢谢或您的回答。我的一位同事也提出了这个建议。但是,如果我们使用它,那么 MAT_NUM 上的条件将被忽略,并且“1-72R”记录的结果集将有所不同,因为我们仅按 NUM2 而不是 MAT_NUM 分区
  • 我做了一个 UNION ALL,效果很好。非常感谢vkp! 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 where MAT_NUM not like '%Fly%) rn from details2 d) x where rn = 1 UNION ALL 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 where MAT_NUM like '%Fly%) rn from details2 d ) x where rn = 1
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-22
  • 2021-01-04
  • 1970-01-01
相关资源
最近更新 更多