How do I flash back a specific column for all rows in a table?
For example, given this table:
select * from t as of scn 1201789714628;
a b
- -
x 1
y 2
z 3
select * from t;
a b
- -
x 4
y 5
z 6
I can flash back a column in a specific row as follows:
update t set b = (select b from t as of scn 1201789714628 where a='x') where a='x';
select * from t;
a b
- -
x 1
y 5
z 6
but I can't figure out the syntax to set b to its previous value this for all rows.
update t t1 set b = (select b from t as of scn 1201789714628) t2 where t1.a = t2.a;
Error at Command Line:11 Column:60
SQL Error: ORA-00933: SQL command not properly ended
You may try this:
update t t1
set b = (select b from (select a, b from t as of scn 1201789714628) t2
where t1.a = t2.a);
P.S. I'd recommend to copy your snapshot in a temporary table if you're not going to update it right now (it can dissapear very soon).
Related
Hi I have two Tables and after Join I want to Insert Data into Third Tables. Problem I am facing is I have to create multiple records based on the value of Join.
Table 1
A B
-------
1 X
2 y
3 x
Table 2
A C
-------
1 Y
2 N
3 Y
I need to join Table 1 and Table 2 on Column A and Based on value of Column C in Table 2 I need to insert Records in Table 3
Rule
If Column C value is 'Y' then insert 3 Records as 'Red','Green','Blue'
If Column C value is 'N then insert 2 records as 'White','Black'
So Result should be
Table 3
A D
-----------
1 Red
1 Green
1 Blue
2 White
2 Black
3 Red
3 Green
3 Blue
Can you let me know how to achieve this using hiveql ? Thanks
You can create a third table Color
Table Color
------------------
Flag Color
Y Red
Y Blue
Y Green
N White
N Black
Now you can join them easily
Select * from Table1 T1
JOIN Table2 T2
ON T1.A = T2.C
JOIN COLOR C
ON T2.C = C.Flag
I have to write a query to match values in two tables, Table A and Table B , Table A is havingvalues in column XYZ as "91517181","915171812", i want to check if its exist in table B or not , but in table B, the value in column ABC is "9151718", but in another column in table B it is having its match length as "10". Which means it is upto "9151718XXX".
So i have to write a query where value from table A should match with value in table B, because in table B, the value is upto 10 characters.
Kindly help...
I think that you need something like this:
table a: table b:
xyz x y
---------- ---------- ---
9151718 9151718 10
91517181 91360 5
913601
select a.xyz, rpad(xyz, b.y, 'x') result, b.x pattern, b.y len
from a
left join b on a.xyz like b.x||'%' and length(a.xyz)<=b.y
xyz result pattern len
---------- ---------- ---------- ---
9151718 9151718xxx 9151718 10
91517181 91517181xx 9151718 10
913601 <- not matched
I think something like that:
select * from a where
exists(select 'x' from b where substr(xyz, 1, y) = x)
x - value in b
y - length in b
I have 2 source tables:
table A: table B:
A_id || A_code B_id || B_code
----- ------- ----- -------
2 t2 1 t1
3 t3 2 t2
4 t4 3 t3
I want to join 2 table use Slowly change dimension
target table:
tgt_id || tgt_code || is_table A || is_table B
----- ------------ ----------- -----------
1 t1 0 x
2 t2 x x
3 t3 x x
4 t4 x 0
I can't check type 'is_table A ' and 'is_table B' when join table.
If I understand correctly, you need to do a full outer join (in SQ or Joiner) on A_id=B_id. Then you can derive the target fields in an expression transformation by doing some null checking as follows:
tgt_id: IIF(ISNULL(A_id),B_id, A_id)
tgt_code: IIF(ISNULL(A_code), B_code, A_code)
is_table_A: IIF(ISNULL(A_id),'0','x')
is_table_B: IIF(ISULL(B_id), '0', 'x')
I try to generate list of products for printing labels, but all of my attempt fail (with connect by level)!
My table:
CREATE TABLE LABELS
(
PRODUCT VARCHAR2(8 BYTE),
Q_ROWS NUMBER
);
Information in the table:
INSERT INTO LABELS (PRODUCT, Q_ROWS) VALUES('D', 3);
INSERT INTO LABELS (PRODUCT, Q_ROWS) VALUES('A', 1);
INSERT INTO LABELS (PRODUCT, Q_ROWS) VALUES('C', 4);
INSERT INTO LABELS (PRODUCT, Q_ROWS) VALUES('B', 2);
Expected Result in a oracle select
PRODUCT
A
B
B
C
C
C
C
D
D
D
Results: (1 row for A, 2 rows for B, 4 rows to C and 3 rows to D)
Can someone help me?
Use LEVEL to get a "table" that counts from 1 to the maximum number of rows:
SELECT LEVEL AS LabelNum
FROM DUAL
CONNECT BY LEVEL <= (SELECT MAX(Q_Rows) FROM Labels)
This will give you the following table:
LabelNum
--------
1
2
3
4
Next, join this to your LABELS table where LabelNum <= Q_Rows. Here's the whole query:
WITH Mult AS (
SELECT LEVEL AS LabelNum
FROM DUAL
CONNECT BY LEVEL <= (SELECT MAX(Q_Rows) FROM Labels)
)
SELECT Product
FROM Labels
INNER JOIN Mult ON LabelNum <= Q_Rows
ORDER BY Product, LabelNum
There's a working SQLFiddle here.
Finally, good job including the create/populate scripts :)
Another approach, using model clause:
select product
from labels
model
partition by (product)
dimension by (1 as indx)
measures(q_rows)
rules(
q_rows[for indx from 1 to q_rows[1] increment 1] = q_rows[1]
)
order by product
result:
PRODUCT
----------
A
B
B
C
C
C
C
D
D
D
SQLFiddle Demo
I had the following query:
SELECT nvl(sum(adjust1),0)
FROM (
SELECT
ManyOperationsOnFieldX adjust1,
a, b, c, d, e
FROM (
SELECT
a, b, c, d, e,
SubStr(balance, INSTR(balance, '[&&2~', 1, 1)) X
FROM
table
WHERE
a >= To_Date('&&1','YYYYMMDD')
AND a < To_Date('&&1','YYYYMMDD')+1
)
)
WHERE
b LIKE ...
AND e IS NULL
AND adjust1>0
AND (b NOT IN ('...','...','...'))
OR (b = '... AND c <> NULL)
I tried to change it to this:
SELECT nvl(sum(adjust1),0)
FROM (
SELECT
ManyOperationsOnFieldX adjust1
FROM (
SELECT
SubStr(balance, INSTR(balance, '[&&2~', 1, 1)) X
FROM
table
WHERE
a >= To_Date('&&1','YYYYMMDD')
AND a < To_Date('&&1','YYYYMMDD')+1
AND b LIKE '..'
AND e IS NULL
AND (b NOT IN ('..','..','..'))
OR (b='..' AND c <> NULL)
)
)
WHERE
adjust1>0
Mi intention was to have all the filtering in the innermost query, and only give to the outer ones the field X which is the one I have to operate a lot. However, the firts (original) query takes a couple of seconds to execute, while the second one won't even finish. I waited for almost 20 minutes and still I wouldn't get the answer.
Is there an obvious reason for this to happen that I might be overlooking?
These are the plans for each of them:
SELECT STATEMENT optimizer=all_rows (cost = 973 Card = 1 bytes = 288)
SORT (aggregate)
PARTITION RANGE (single) (cost=973 Card = 3 bytes = 864)
TABLE ACCESS (full) OF "table" #3 TABLE Optimizer = analyzed(cost=973 Card = 3 bytes=564)
SELECT STATEMENT optimizer=all_rows (cost = 750.354 Card = 1 bytes = 288)
SORT (aggregate)
PARTITION RANGE (ALL) (cost=759.354 Cart = 64.339 bytes = 18.529.632)
TABLE ACCESS (full) OF "table" #3 TABLE Optimizer = analyzed(cost=750.354 Card = 64.339 bytes=18.529.632)
Your two queries are not identical.
the logical operator AND is evaluated before the operator OR:
SQL> WITH data AS
2 (SELECT rownum id
3 FROM dual
4 CONNECT BY level <= 10)
5 SELECT *
6 FROM data
7 WHERE id = 2
8 AND id = 3
9 OR id = 5;
ID
----------
5
So your first query means: Give me the big SUM over this partition when the data is this way.
Your second query means: give me the big SUM over (this partition when the data is this way) or (when the data is this other way [no partition elimination hence big full scan])
Be careful when mixing the logical operators AND and OR. My advice would be to use brackets so as to avoid any confusion.
It is all about your OR... Try this:
SELECT nvl(sum(adjust1),0)
FROM (
SELECT
ManyOperationsOnFieldX adjust1
FROM (
SELECT
SubStr(balance, INSTR(balance, '[&&2~', 1, 1)) X
FROM
table
WHERE
a >= To_Date('&&1','YYYYMMDD')
AND a < To_Date('&&1','YYYYMMDD')+1
AND (
b LIKE '..'
AND e IS NULL
AND (b NOT IN ('..','..','..'))
OR (b='..' AND c <> NULL)
)
)
)
WHERE
adjust1>0
Because you have the OR inline with the rest of your AND statements with no parenthesis, the 2nd version isn't limiting the data checked to just the rows that fall in the date filter. For more info, see the documentation of Condition Precedence