Oracle 10g:如何有条件地从 table A 到 B 插入行

Oracle 10g: How insert conditionally rows from table A to B based

得到了一个table这样的

|----------|----------|
|  DT      |  FLAG    |
|----------|----------|
| 2015-MAY |  E       |
| 2015-JUN |  H       |
| 2015-OCT |  S       |
| 2016-FEB |  E       |
|----------|----------|

我想在 B 中插入 A 的 flag 聚合数据匹配给定模式的行。

此查询执行以下聚合:

     SELECT
            (lag(rep.flag) over (ORDER BY rep.DECLARATIONPERIOD) || flag) AS ERRCODE,
            (lag(rep.DECLARATIONPERIOD) over (ORDER BY rep.DECLARATIONPERIOD)) AS DECFROM, DECLARATIONPERIOD AS DECTO
    FROM  XE_ERR_OVLP rep;

结果(table A):

|----------|---------------|---------------|
|  FLAG    |  DTFROM       |  DTFTO        |
|----------|---------------|---------------|
|  VV      |    2014-02-01 |    2014-03-01 |
|  VE      |    2014-03-01 |    2014-04-01 |
|  EE      |    2014-04-01 |    2014-05-01 |
|  EV      |    2014-05-01 |    2014-06-01 |
|  VV      |    2014-06-01 |    2014-07-01 |
|  VS      |    2014-07-01 |    2014-08-31 |
|----------|---------------|---------------|

demo

我想从 table (A) 填充此 table (B),因为 FLAG 的值仅匹配特定值(例如 EEHH):

|----------|---------------|---------------|
|  FLAG    |  DTFROM       |  DTFTO        |
|----------|---------------|---------------|
|  ...     | ...           | ...           |
|----------|---------------| --------------|

如果可能的话(在聚合时)。

欢迎提出任何正确的建议

这符合您的描述:

insert into b (dt, flag)
    select dt, flag
    from a
    where flag in ('E', 'H');

我不确定它与查询有何关系,这些查询比您的示例数据和问题复杂得多。

这是一个操作顺序问题:请注意,在过滤之前,我们使用派生的 table 来具体化分析的结果。 SELECT 在执行 where 子句之前不会执行,因此 ERRCODE 别名对于 where 子句是未知的。

SQL操作顺序网上可以找到,我就不去restate;但在这种情况下,以下是重要的 elements/order。您会注意到 link 明确说明了您的问题:Window 函数 ... 不适用于 WHERE 子句,该子句发生在 window 函数求值之前。

  1. 来自
  2. 哪里
  3. SELECT

这意味着 WHERE 子句还不知道 ERRCODE;所以它不能被它限制。这通常通过使用派生的 table/inline 视图或常见的 table 表达式来解决。

这是内联 view/derived table:

   INSERT INTO XE_ERR_RANG
      SELECT Z.* 
      FROM (SELECT EMPLOYERID
                 , EMPLOYEEID
                 , lag(DECLARATIONPERIOD) over (ORDER BY DECLARATIONPERIOD) AS DECFROM
                 , DECLARATIONPERIOD AS DECTO
                 , lag(flag) over (ORDER BY DECLARATIONPERIOD) || flag AS ERRCODE
            FROM XE_ERR_OVLP) Z
      WHERE Z.ERRCODE in ('HS', 'SE'); 

使用通用 table 表达式 (CTE) 的替代方法:

未测试:但您说 oracle 10g 似乎支持 CTE;但不是递归;如果它支持 CTE 之前的插入语法,那么应该可以工作...

INSERT INTO XE_ERR_RANG

WITH Z as (SELECT EMPLOYERID
                , EMPLOYEEID
                , lag(DECLARATIONPERIOD) over (ORDER BY DECLARATIONPERIOD) AS DECFROM
                , DECLARATIONPERIOD AS DECTO
                , lag(flag) over (ORDER BY DECLARATIONPERIOD) || flag AS ERRCODE
           FROM XE_ERR_OVLP)

SELECT * 
FROM Z
WHERE ERRCODE in ('HS', 'SE');