Home » SQL & PL/SQL » SQL & PL/SQL » Oracle sql query to pick current and previous records (Oracle, 11g, Windows)
Oracle sql query to pick current and previous records [message #622880] |
Mon, 01 September 2014 06:24 |
|
surestce
Messages: 2 Registered: September 2014
|
Junior Member |
|
|
have a table that contains all transactions with Quantity column. Need to calculate the cumulative total of quantity of transaction group and update in each transaction row.
TRANSACTION table:
id(PK) group_id, txn_id, txn_date, Quantity, cumulative_qty
1 1 111 12-AUG-14 10 10
2 1 112 13-AUG-14 -5 5
3 1 113 14-AUG-14 2 7
4 2 221 23-AUG-14 15 15
5 2 222 23-AUG-14 15 30
I wrote MERGE INTO script and it is working file. But the problem is that it is updating old records also. This table is having huge volume of data and that hit is performance issue.
Now I need a merge script that need to fetch only unprocessed new records (cumulative_qty is NULL) and add the Quantity with last cumulative_qty value.
Suppose, if there is any new transactions for the same group, the select of merge should pick up old and new records alone and update the new record.
id(PK) group_id, txn_id, txn_date, Quantity, cumulative_qty
6 1 114 25-AUG-14 5 NULL
7 1 115 26-AUG-14 2 NULL
8 2 223 25-AUG-14 -10 NULL
merge into
txn t1
using (
select
txn_id,
lag(cumulative_qty, 1) over (
partition by group_id
order by txn_id
) as prev_cum_qty
from
txn
) x
on
(t1.txn_id = x.txn_id)
when matched then update set
cumulative_qty = quantity + prev_cum_qty
where
cumulative_qty is null;
In the above merge query, the select query returns all 7 rows to process and then merge 2 rows. But I want the select query that should return only 4 rows (id: 3,5,6,7, i.e. the last cumulative row (order by max date and id) and unprocessed rows only.
I am using Oracle 11g.
Please help me. Thanks in advance.
Lalit : Added code tags, but unable to format the code.
LF: fixed topic title typo
[Updated on: Mon, 01 September 2014 06:39] by Moderator Report message to a moderator
|
|
|
|
Re: Oracle sql query to pick current and previous records [message #622890 is a reply to message #622880] |
Mon, 01 September 2014 06:59 |
|
surestce
Messages: 2 Registered: September 2014
|
Junior Member |
|
|
Hi,
Script to create a table and insert record:
create table txn (
txn_id numeric(9) not null constraint PK_txn primary key,
group_id numeric(9),
txn_date date,
quantity numeric(9),
cumulative_qty numeric(9)
);
create index ix_group_txn on txn(group_id, txn_id);
insert into txn values (1, 1, DATE'2014-08-12', 10, 10);
insert into txn values (2, 1, DATE'2014-08-13', -5, 5);
insert into txn values (3, 1, DATE'2014-08-14', 2, 7);
insert into txn values (4, 2, DATE'2014-08-23', 15, 15);
insert into txn values (5, 2, DATE'2014-08-23', 15, 30);
insert into txn values (6, 1, DATE'2014-08-25', 5, NULL);
insert into txn values (7, 1, DATE'2014-08-26', 2, NULL);
insert into txn values (8, 2, DATE'2014-08-25', -10, NULL);
insert into txn values (9, 3, DATE'2014-08-28', 100, NULL);
Table having processed Records:
id(PK) group_id, txn_id, txn_date, Quantity, cumulative_qty
1 1 111 12-AUG-14 10 10
2 1 112 13-AUG-14 -5 5
3 1 113 14-AUG-14 2 7
4 2 221 23-AUG-14 15 15
5 2 222 23-AUG-14 15 30
Table refreshed with unprocessed Records:
id(PK) group_id, txn_id, txn_date, Quantity, cumulative_qty
1 1 111 12-AUG-14 10 10
2 1 112 13-AUG-14 -5 5
3 1 113 14-AUG-14 2 7
4 2 221 23-AUG-14 15 15
5 2 222 23-AUG-14 15 30
6 1 114 26-AUG-14 5 NULL
7 1 115 27-AUG-14 2 NULL
8 2 223 28-AUG-14 -10 NULL
9 3 333 29-AUG-14 125 NULL
Current Merge script to update unprocessed records with cumulative value:
MERGE INTO txn t1 USING
(SELECT txn_id,
lag(cumulative_qty, 1) over ( partition BY group_id order by txn_id ) AS prev_cum_qty
FROM txn
) x ON (t1.txn_id = x.txn_id)
WHEN matched THEN
UPDATE
SET cumulative_qty = quantity + prev_cum_qty
WHERE cumulative_qty IS NULL;
In the above merge query, the select query fetching all the rows (in this case all 9 records) and merge 4 records. This hitting performance issue. I want the select query to return only the unprocessed rows(txn_id: 6,7,8,9) and latest processed rows(txn_id: 3,5).
SELECT txn_id,
lag(cumulative_qty, 1) over ( partition BY group_id order by txn_id ) AS prev_cum_qty
FROM txn;
[Updated on: Mon, 01 September 2014 07:04] Report message to a moderator
|
|
|
Re: Oracle sql query to pick current and previous records [message #622893 is a reply to message #622890] |
Mon, 01 September 2014 07:47 |
|
Michel Cadot
Messages: 68645 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
Here's a starter:
SQL> select * from txn order by group_id, txn_id;
TXN_ID GROUP_ID TXN_DATE QUANTITY CUMULATIVE_QTY
---------- ---------- ----------- ---------- --------------
1 1 12-AUG-2014 10 10
2 1 13-AUG-2014 -5 5
3 1 14-AUG-2014 2 7
6 1 25-AUG-2014 5
7 1 26-AUG-2014 2
4 2 23-AUG-2014 15 15
5 2 23-AUG-2014 15 30
8 2 25-AUG-2014 -10
9 3 28-AUG-2014 100
9 rows selected.
SQL> merge
2 into txn t
3 using (with
4 maxtxn as (
5 select group_id, max(txn_id) maxtxn
6 from txn
7 where cumulative_qty is not null
8 group by group_id
9 )
10 select t.group_id, t.txn_id, t.quantity,
11 last_value (t.cumulative_qty ignore nulls)
12 over (partition by t.group_id order by t.txn_id)
13 + sum(decode(t.txn_id,m.maxtxn,0,t.quantity)) over
14 (partition by t.group_id
15 order by t.txn_id
16 rows between unbounded preceding and current row)
17 cumulative_qty
18 from txn t, maxtxn m
19 where t.group_id = m.group_id
20 and t.txn_id >= m.maxtxn) x
21 on (t.txn_id = x.txn_id)
22 when matched then
23 update set cumulative_qty = nvl(x.cumulative_qty, x.quantity)
24 where cumulative_qty is null
25 /
3 rows merged.
SQL> select * from txn order by group_id, txn_id;
TXN_ID GROUP_ID TXN_DATE QUANTITY CUMULATIVE_QTY
---------- ---------- ----------- ---------- --------------
1 1 12-AUG-2014 10 10
2 1 13-AUG-2014 -5 5
3 1 14-AUG-2014 2 7
6 1 25-AUG-2014 5 12
7 1 26-AUG-2014 2 14
4 2 23-AUG-2014 15 15
5 2 23-AUG-2014 15 30
8 2 25-AUG-2014 -10 20
9 3 28-AUG-2014 100
9 rows selected.
The SELECT retrieves only 5 rows (1 per group with not null cumulative_qty + the rows to update).
To do: the groups that have no cumulative_qty in any row.
|
|
|
Re: Oracle sql query to pick current and previous records [message #622897 is a reply to message #622893] |
Mon, 01 September 2014 08:51 |
|
Michel Cadot
Messages: 68645 Registered: March 2007 Location: Nanterre, France, http://...
|
Senior Member Account Moderator |
|
|
Here's a statement that handles this latter case:
SQL> select * from txn order by group_id, txn_id;
TXN_ID GROUP_ID TXN_DATE QUANTITY CUMULATIVE_QTY
---------- ---------- ----------- ---------- --------------
1 1 12-AUG-2014 10 10
2 1 13-AUG-2014 -5 5
3 1 14-AUG-2014 2 7
6 1 25-AUG-2014 5
7 1 26-AUG-2014 2
4 2 23-AUG-2014 15 15
5 2 23-AUG-2014 15 30
8 2 25-AUG-2014 -10
9 3 28-AUG-2014 100
9 rows selected.
SQL> merge
2 into txn t
3 using (with
4 maxtxn as (
5 select group_id, max(txn_id) maxtxn
6 from txn
7 where cumulative_qty is not null
8 group by group_id
9 union all
10 select group_id, min(txn_id)
11 from txn
12 group by group_id
13 having max(cumulative_qty) is null
14 )
15 select t.group_id, t.txn_id, t.quantity,
16 nvl(last_value (t.cumulative_qty ignore nulls)
17 over (partition by t.group_id order by t.txn_id),
18 t.quantity)
19 + sum(decode(t.txn_id,m.maxtxn,0,t.quantity)) over
20 (partition by t.group_id
21 order by t.txn_id
22 rows between unbounded preceding and current row)
23 cumulative_qty
24 from txn t, maxtxn m
25 where t.group_id = m.group_id
26 and t.txn_id >= m.maxtxn) x
27 on (t.txn_id = x.txn_id)
28 when matched then
29 update set cumulative_qty = nvl(x.cumulative_qty, x.quantity)
30 where cumulative_qty is null
31 /
4 rows merged.
SQL> select * from txn order by group_id, txn_id;
TXN_ID GROUP_ID TXN_DATE QUANTITY CUMULATIVE_QTY
---------- ---------- ----------- ---------- --------------
1 1 12-AUG-2014 10 10
2 1 13-AUG-2014 -5 5
3 1 14-AUG-2014 2 7
6 1 25-AUG-2014 5 12
7 1 26-AUG-2014 2 14
4 2 23-AUG-2014 15 15
5 2 23-AUG-2014 15 30
8 2 25-AUG-2014 -10 20
9 3 28-AUG-2014 100 100
9 rows selected.
|
|
|
Re: Oracle sql query to pick current and previous records [message #622899 is a reply to message #622893] |
Mon, 01 September 2014 09:14 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
Michel,
Your solution doesn't have a better plan:
SQL> set linesize 132
SQL> explain plan for
2 MERGE INTO txn t1 USING
3 (SELECT txn_id,
4 lag(cumulative_qty, 1) over ( partition BY group_id order by txn_id ) AS prev_cum_qty
5 FROM txn
6 ) x ON (t1.txn_id = x.txn_id)
7 WHEN matched THEN
8 UPDATE
9 SET cumulative_qty = quantity + prev_cum_qty
10 WHERE cumulative_qty IS NULL
11 /
Explained.
SQL> select *
2 from table(dbms_xplan.display)
3 /
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3439448641
-------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 9 | 900 | 4 (25)| 00:00:01 |
| 1 | MERGE | TXN | | | | |
| 2 | VIEW | | | | | |
|* 3 | HASH JOIN | | 9 | 891 | 4 (25)| 00:00:01 |
| 4 | VIEW | | 9 | 234 | 0 (0)| 00:00:01 |
| 5 | WINDOW BUFFER | | 9 | 351 | 0 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
| 6 | TABLE ACCESS BY INDEX ROWID| TXN | 9 | 351 | 0 (0)| 00:00:01 |
| 7 | INDEX FULL SCAN | IX_GROUP_TXN | 9 | | 0 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | TXN | 9 | 657 | 3 (0)| 00:00:01 |
-------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("T1"."TXN_ID"="X"."TXN_ID")
Note
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
-----
- dynamic sampling used for this statement (level=2)
24 rows selected.
SQL> explain plan for
2 merge
3 into txn t
4 using (with
5 maxtxn as (
6 select group_id, max(txn_id) maxtxn
7 from txn
8 where cumulative_qty is not null
9 group by group_id
10 )
11 select t.group_id, t.txn_id, t.quantity,
12 last_value (t.cumulative_qty ignore nulls)
13 over (partition by t.group_id order by t.txn_id)
14 + sum(decode(t.txn_id,m.maxtxn,0,t.quantity)) over
15 (partition by t.group_id
16 order by t.txn_id
17 rows between unbounded preceding and current row)
18 cumulative_qty
19 from txn t, maxtxn m
20 where t.group_id = m.group_id
21 and t.txn_id >= m.maxtxn) x
22 on (t.txn_id = x.txn_id)
23 when matched then
24 update set cumulative_qty = nvl(x.cumulative_qty, x.quantity)
25 where cumulative_qty is null
26 /
Explained.
SQL> select *
2 from table(dbms_xplan.display)
3 /
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Plan hash value: 3559473924
------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 1 | 100 | 5 (20)| 00:00:01 |
| 1 | MERGE | TXN | | | | |
| 2 | VIEW | | | | | |
| 3 | NESTED LOOPS | | | | | |
| 4 | NESTED LOOPS | | 1 | 125 | 5 (20)| 00:00:01 |
| 5 | VIEW | | 1 | 52 | 4 (25)| 00:00:01 |
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
| 6 | WINDOW SORT | | 1 | 65 | 4 (25)| 00:00:01 |
| 7 | NESTED LOOPS | | 1 | 65 | 3 (0)| 00:00:01 |
| 8 | TABLE ACCESS FULL | TXN | 9 | 468 | 3 (0)| 00:00:01 |
|* 9 | VIEW PUSHED PREDICATE | | 1 | 13 | 0 (0)| 00:00:01 |
|* 10 | FILTER | | | | | |
| 11 | SORT AGGREGATE | | 1 | 39 | | |
|* 12 | TABLE ACCESS BY INDEX ROWID| TXN | 1 | 39 | 0 (0)| 00:00:01 |
|* 13 | INDEX RANGE SCAN | IX_GROUP_TXN | 1 | | 0 (0)| 00:00:01 |
|* 14 | INDEX UNIQUE SCAN | PK_TXN | 1 | | 0 (0)| 00:00:01 |
| 15 | TABLE ACCESS BY INDEX ROWID | TXN | 1 | 73 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
9 - filter("T"."TXN_ID">="M"."MAXTXN")
10 - filter(COUNT(*)>0)
12 - filter("CUMULATIVE_QTY" IS NOT NULL)
13 - access("GROUP_ID"="T"."GROUP_ID")
14 - access("T"."TXN_ID"="X"."TXN_ID")
Note
PLAN_TABLE_OUTPUT
------------------------------------------------------------------------------------------------------------------------------------
-----
- dynamic sampling used for this statement (level=2)
35 rows selected.
SQL>
Also, OP needs to clarify unprocessed rows. Can unprocessed row transaction date be less than processed row transaction date? If it can, we need to recalculate all cumulative_qty. But main thing is non-scalable design. Storing cumulative values implies serialization. We will get bad results if multiple sessions will try to recalculate cumulative_qty at the same time.
Anyway, I'l assume unprocessed row transaction date is greater than processed row transaction date and process will be serialized. First issue we face here is lack of indexes. I will drop OP provided index and will create:
create index txn_idx1
on txn(
nvl2(cumulative_qty,null,1),
quantity
)
/
create index txn_idx2
on txn(
group_id,
txn_date,
cumulative_qty
)
/
Now:
SQL> select * from txn order by group_id,txn_date;
TXN_ID GROUP_ID TXN_DATE QUANTITY CUMULATIVE_QTY
---------- ---------- --------- ---------- --------------
1 1 12-AUG-14 10 10
2 1 13-AUG-14 -5 5
3 1 14-AUG-14 2 7
6 1 25-AUG-14 5
7 1 26-AUG-14 2
4 2 23-AUG-14 15 15
5 2 23-AUG-14 15 30
8 2 25-AUG-14 -10
9 3 28-AUG-14 100
9 rows selected.
SQL> set autotrace on
SQL> merge
2 into txn t
3 using(
4 select rowid rid,
5 sum(quantity) over(partition by group_id order by txn_date) +
6 nvl(
7 (
8 select max(b.cumulative_qty) keep(dense_rank last order by txn_date)
9 from txn b
10 where b.group_id = a.group_id
11 and b.txn_date < a.txn_date
12 and b.cumulative_qty is not null
13 ),
14 0
15 ) cumulative_qty
16 from txn a
17 where nvl2(cumulative_qty,null,1) = 1
18 ) s
19 on (
20 t.rowid = s.rid
21 )
22 when matched
23 then update
24 set cumulative_qty = s.cumulative_qty
25 /
4 rows merged.
Execution Plan
----------------------------------------------------------
Plan hash value: 2525700079
---------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
---------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 1 | 61 | 4 (25)| 00:00:01 |
| 1 | MERGE | TXN | | | | |
| 2 | SORT AGGREGATE | | 1 | 35 | | |
|* 3 | INDEX RANGE SCAN | TXN_IDX2 | 1 | 35 | 1 (0)| 00:00:01 |
| 4 | VIEW | | | | | |
| 5 | NESTED LOOPS | | 1 | 98 | 4 (25)| 00:00:01 |
| 6 | VIEW | | 1 | 25 | 3 (34)| 00:00:01 |
| 7 | WINDOW SORT | | 1 | 50 | 3 (34)| 00:00:01 |
| 8 | TABLE ACCESS BY INDEX ROWID| TXN | 1 | 50 | 2 (0)| 00:00:01 |
|* 9 | INDEX RANGE SCAN | TXN_IDX1 | 1 | | 1 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY USER ROWID | TXN | 1 | 73 | 1 (0)| 00:00:01 |
---------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
3 - access("B"."GROUP_ID"=:B1 AND "B"."TXN_DATE"<:B2)
filter("B"."CUMULATIVE_QTY" IS NOT NULL)
9 - access(NVL2("CUMULATIVE_QTY",NULL,1)=1)
Note
-----
- dynamic sampling used for this statement (level=2)
Statistics
----------------------------------------------------------
0 recursive calls
38 db block gets
5 consistent gets
0 physical reads
0 redo size
847 bytes sent via SQL*Net to client
1503 bytes received via SQL*Net from client
3 SQL*Net roundtrips to/from client
2 sorts (memory)
0 sorts (disk)
4 rows processed
SQL> set autotrace off
SQL> select * from txn order by group_id,txn_date;
TXN_ID GROUP_ID TXN_DATE QUANTITY CUMULATIVE_QTY
---------- ---------- --------- ---------- --------------
1 1 12-AUG-14 10 10
2 1 13-AUG-14 -5 5
3 1 14-AUG-14 2 7
6 1 25-AUG-14 5 12
7 1 26-AUG-14 2 14
4 2 23-AUG-14 15 15
5 2 23-AUG-14 15 30
8 2 25-AUG-14 -10 20
9 3 28-AUG-14 100 100
9 rows selected.
SQL>
However, we are executing select list subquery for every row where cumulative_qty is null (for every unprocessed row), so it all depends on how many unprocessed rows there are. Full scan will be faster for large(r) number of unprocessed rows.
SY.
|
|
|
|
Re: Oracle sql query to pick current and previous records [message #622919 is a reply to message #622902] |
Mon, 01 September 2014 14:11 |
Solomon Yakobson
Messages: 3273 Registered: January 2010 Location: Connecticut, USA
|
Senior Member |
|
|
Michel Cadot wrote on Mon, 01 September 2014 11:21
We can't compare as OP's statement is wrong and does not give the expected result.
Oops. OP complained about his solution performance but never mentioned wrong results, so I assumed it works OK. Anyway, OP wrote: "In the above merge query, the select query fetching all the rows (in this case all 9 records) and merge 4 records. This hitting performance issue. I want the select query to return only the unprocessed rows(txn_id: 6,7,8,9) and latest processed rows(txn_id: 3,5)". We have to add last_txn_flag column to implement the above:
SQL> select *
2 from txn
3 order by group_id,
4 txn_date
5 /
TXN_ID GROUP_ID TXN_DATE QUANTITY CUMULATIVE_QTY LAST_TXN_FLAG
---------- ---------- --------- ---------- -------------- -------------
1 1 12-AUG-14 10 10 0
2 1 13-AUG-14 -5 5 0
3 1 14-AUG-14 2 7 1
6 1 25-AUG-14 5
7 1 26-AUG-14 2
4 2 23-AUG-14 15 15 0
5 2 23-AUG-14 15 30 1
8 2 25-AUG-14 -10
9 3 28-AUG-14 100
9 rows selected.
We also need FBI:
create index txn_idx1
on txn(
nvl2(cumulative_qty,last_txn_flag,1),
group_id,
txn_date,
cumulative_qty,
quantity
)
/
Now:
SQL> set autotrace on explain
SQL> merge
2 into txn t
3 using(
4 select rowid rid,
5 sum(
6 nvl2(cumulative_qty,0,quantity) + nvl(cumulative_qty,0)
7 ) over(partition by group_id order by txn_date) cumulative_qty,
8 lead(0,1,1) over(partition by group_id order by txn_date) last_txn_flag
9 from txn a
10 where nvl2(cumulative_qty,last_txn_flag,1) = 1
11 ) s
12 on (
13 t.rowid = s.rid
14 )
15 when matched
16 then update
17 set cumulative_qty = s.cumulative_qty,
18 last_txn_flag = s.last_txn_flag
19 /
6 rows merged.
Execution Plan
----------------------------------------------------------
Plan hash value: 3419488159
------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------
| 0 | MERGE STATEMENT | | 1 | 77 | 3 (34)| 00:00:01 |
| 1 | MERGE | TXN | | | | |
| 2 | VIEW | | | | | |
| 3 | NESTED LOOPS | | 1 | 114 | 3 (34)| 00:00:01 |
| 4 | VIEW | | 1 | 28 | 2 (50)| 00:00:01 |
| 5 | WINDOW BUFFER | | 1 | 73 | 2 (50)| 00:00:01 |
|* 6 | INDEX RANGE SCAN | TXN_IDX1 | 1 | 73 | 1 (0)| 00:00:01 |
| 7 | TABLE ACCESS BY USER ROWID| TXN | 1 | 86 | 1 (0)| 00:00:01 |
------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
6 - access(NVL2("CUMULATIVE_QTY","LAST_TXN_FLAG",1)=1)
Note
-----
- dynamic sampling used for this statement (level=2)
SQL> set autotrace off
SQL> select *
2 from txn
3 order by group_id,
4 txn_date
5 /
TXN_ID GROUP_ID TXN_DATE QUANTITY CUMULATIVE_QTY LAST_TXN_FLAG
---------- ---------- --------- ---------- -------------- -------------
1 1 12-AUG-14 10 10 0
2 1 13-AUG-14 -5 5 0
3 1 14-AUG-14 2 7 0
6 1 25-AUG-14 5 12 0
7 1 26-AUG-14 2 14 1
4 2 23-AUG-14 15 15 0
5 2 23-AUG-14 15 30 0
8 2 25-AUG-14 -10 20 1
9 3 28-AUG-14 100 100 1
9 rows selected.
SQL>
SY.
|
|
|
|
Goto Forum:
Current Time: Wed Apr 24 23:14:29 CDT 2024
|