Reputation: 2125
Got a table A like this
|----------|----------|
| DT | FLAG |
|----------|----------|
| 2015-MAY | E |
| 2015-JUN | H |
| 2015-OCT | S |
| 2016-FEB | E |
|----------|----------|
I want to insert in B the rows for which the flag
aggregated data of A match a given pattern.
This query do the aggregation below:
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;
Result (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 |
|----------|---------------|---------------|
See demo
I would like to populate this table (B) from the table (A), for the value of FLAG that match certain value only (eg EE
and HH
):
|----------|---------------|---------------|
| FLAG | DTFROM | DTFTO |
|----------|---------------|---------------|
| ... | ... | ... |
|----------|---------------| --------------|
If possible on the fly (while aggregating).
Any suggestion to get it right welcome
Upvotes: 0
Views: 53
Reputation: 35333
It's an order of operation issue: Note we materialize the results of the analytic using a derived table before we filter on it. The SELECT doesn't execute until the where clause has been executed so the ERRCODE alias is unknown to the where clause.
SQL order of operations can be found online, I'm not going to restate; but in this case the below are the important elements/order. You'll note the link specifically states your issue: Window functions ... are not available to the WHERE clause, which happened before the evaluation of the window function.
This means the WHERE Clause doesn't know about ERRCODE yet; so it can't limit by it. This is generally solved by using a derived table/inline view or a common table expression.
Here's the inline 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');
Alternative approach using a common table expression (CTE):
Untested: but you said oracle 10g appears to support CTE; but not recursion; so should work if it supports the insert syntax before the 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');
Upvotes: 1
Reputation: 1269933
This does what you describe:
insert into b (dt, flag)
select dt, flag
from a
where flag in ('E', 'H');
I'm not sure how it relates to the queries, which are considerably more complicated than your sample data and question.
Upvotes: 1