Oracle 10g: как условно вставить строки из таблицы A в B - PullRequest
0 голосов
/ 23 мая 2018

Получил таблицу A, подобную этой

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

Я хочу вставить в B строки, для которых flag агрегированные данные A соответствуют заданному шаблону.

Этот запрос выполняетагрегация ниже:

     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;

Результат (таблица 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

Я хотел бы заполнить эту таблицу (B) из таблицы (A) для значения FLAG, которое соответствует только определенному значению (например, EE и HH):

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

Если возможно на лету (при агрегировании).

Любые предложения, чтобы сделать это правильно, добро пожаловать

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Это проблема порядка операций: обратите внимание, мы материализуем результаты аналитики, используя производную таблицу, прежде чем отфильтруем ее.SELECT не выполняется до тех пор, пока не будет выполнено предложение where, поэтому псевдоним ERRCODE неизвестен предложению where.

Порядок операций SQL можно найти в Интернете, я не собираюсь пересматривать ;но в этом случае ниже приведены важные элементы / порядок.Вы заметите, что в ссылке конкретно указывается ваша проблема: оконные функции ... недоступны предложению WHERE, которое произошло до оценки оконной функции.

  1. FROM
  2. WHERE
  3. SELECT

Это означает, что предложение WHERE еще не знает о ERRCODE;так что это не может ограничивать это.Обычно это решается с помощью производной таблицы / встроенного представления или общего табличного выражения.

Вот встроенное представление / производная таблица:

   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'); 

Альтернативный подход с использованием общего табличного выражения (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'); 
0 голосов
/ 23 мая 2018

Это то, что вы описываете:

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

Я не уверен, как это относится к запросам, которые значительно сложнее, чем ваши примеры данных и вопросы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...