I have database design like this...
dated ref weight no. address
21-03-2013 ABCD/EDFG 1234 A45 A1
20-03-2013 ABCD/EDFG 789 A56 A2
25-03-2013 ABCD/EDFG 6981 A99 A5
23-03-2013 GAJHS/ASDH 72 A82 GV
what i want here in the query result is something like this....
search on the basis of no.
but then, it has to see if the ref of that row exists more times and if it exists then it has to add the weight of all such rows keeping in mind dated of all such records should be less than the dated of selected no..
example -
no. = A56
three rows exist with same ref(ABCD/EDFG)
but dated of A56 is lower among all so results should be
ref ------ weight -------- no. -------- address
ABCD/EDFG ------ 789 ----------- A56 -------- A2
but in the case of no. = A99 results should be like this -
ref ----------- weight -------- no. -------- address
ABCD/EDFG --- (789+6981+1234) ----------- A99 -------- A5
as dated of A99 is greater than other two records.
please help me in this query.
select
ref,
sum(weight) over (partition by ref order by dated) as weight,
no,
address
from
...
Related
Good evening,
I am trying to understand in which cases the sequence would be used, for the example below, since the rowids would not always give me a single row to manage the changes.
Why consider a sequence of additional fields?
I will be grateful if you could clarify the doubt, with some example.
Thank you so much,
Greetings.
CREATE MATERIALIZED VIEW LOG ON sales
WITH ROWID, SEQUENCE(amount_sold, time_id, prod_id)
INCLUDING NEW VALUES;
Now imagine that you want to create a materialized view that contains aggregates on this table. Because the materialized view log has been created with all referenced columns in the materialized view's defining query, the materialized view is fast refreshable. If DML is applied against the sales table, then the changes are reflected in the materialized view when the commit is issued.
CREATE MATERIALIZED VIEW sum_sales
REFRESH FAST ON COMMIT AS
SELECT s.time_id, COUNT(*) AS count_grp,
SUM(s.amount_sold) AS sum_dollar_sales,
COUNT(s.amount_sold) AS count_dollar_sales
FROM sales s
GROUP BY s.time_id;
Without using the sequence, you will have the following error
ORA-12033: cannot use filter columns from materialized view log on "ADMIN"."SALES"
So let me try to explain why, by using a Testcase
drop table sales;
create table sales (time_id number, prod_id number, amount_sold number)
CREATE MATERIALIZED VIEW LOG ON sales
WITH ROWID, SEQUENCE(amount_sold, time_id, prod_id)
INCLUDING NEW VALUES;
truncate table sales;
insert into sales values (1,1,23);
insert into sales values (1,2,23);
commit;
select time_id, sum(amount_sold) from sales group by time_id;
TIME_ID SUM(AMOUNT_SOLD)
------- ----------------
1 46
Now Imagine, that you will modify a row multiple times.
update sales set amount_sold = 55 where time_id = 1 and PROD_ID = 1;
update sales set amount_sold = 12 where time_id = 1 and PROD_ID = 1;
select time_id, sum(amount_sold) from sales group by time_id;
TIME_ID SUM(AMOUNT_SOLD)
------- ----------------
1 35
your new amount_sold is 35. How to do a fast refresh without reading the value for the row (1,2) because you only modified (1,1)
select * from MLOG$_SALES where DMLTYPE$$ != 'I' order by ;
AMOUNT_SOLD TIME_ID PROD_ID M_ROW$$ SEQUENCE$$ SNAPTIME$$ DMLTYPE$$ OLD_NEW$$ CHANGE_VECTOR$$ XID$$
----------- ------- ------- ------------------ ---------- -------------------- --------- --------- --------------- ----------------
23 1 1 AAAwaSAAAAAAFpTAAA 105 4000-01-01T00:00:00Z U U CA== 4222223434942993
55 1 1 AAAwaSAAAAAAFpTAAA 106 4000-01-01T00:00:00Z U N CA== 4222223434942993
55 1 1 AAAwaSAAAAAAFpTAAA 107 4000-01-01T00:00:00Z U U CA== 4222223434942993
12 1 1 AAAwaSAAAAAAFpTAAA 108 4000-01-01T00:00:00Z U N CA== 4222223434942993
So you can use the previous value 46 and increment/decrement using the old/new value as follow
select 46 - 23 + 55 - 55 + 12 as newval from dual;
NEWVAL
------
35
You can also do the same when doing a delete
This is not possible having only the rowid. To generate the new value 35 you need to read an unmodified value, so you cannot do a fast refresh.
Hope that this can help you to understand in which cases the sequence is used
Does anybody know how to do Linear Referencing in Oracle?
I have a table with my route geometries, like
id routename geometry
-- --------- ----------
1 Mainstreet SDO_GEOMETRY
2 5th Avenue SDO_GEOMETRY
and I have a table with my events, like
id routename velocity from to
-- --------- -------- ---- ----
1 Mainstreet 75mph 0.0 52.5
2 Mainstreet 45mph 52.5 102.0
3 5th Avenue 75mph 0.0 78.0
I want to get the events as standard SDO_GEOMETRIES, like:
id routename velocity geometry
-- --------- -------- --------
1 Mainstreet 75mph SDO_GEOMETRY
2 Mainstreet 45mph SDO_GEOMETRY
3 5th Avenue 75mph SDO_GEOMETRY
In ArcGis or Geomedia it is very simple to achieve that... must be possible in Oracle I guess?
I have two tables affiliation and customer, in that i have data like this
aff_id From_cus_id
------ -----------
1 10
2 20
3 30
4 40
5 50
cust_id cust_aff_id
------- -------
10
20
30
40
50
i need to update data for cust_aff_id column from affiliation table which is aff_id like below
cust_id cust_aff_id
------- -------
10 1
20 2
30 3
40 4
50 5
could u please give reply if anyone knows......
Oracle doesn't have an UPDATE with join syntax, but you can use a subquery instead:
UPDATE customer
SET customer.cust_aff_id =
(SELECT aff_id FROM affiliation WHERE From_cus_id = customer.cust_id)
merge into customer t2
using affiliation t1 on (t1.From_cus_id =t2.cust_id )
WHEN MATCHED THEN
update set t2.cust_aff_id = t1.aff_id
;
Here is an update with join syntax. This, quite reasonably, works only if from_cus_id is primary key in the first table and cust_id is foreign key in the second table, referencing the first table. Without these conditions, the requirement doesn't make much sense in the first place anyway... but Oracle requires that these constraints be stated explicitly in the tables. This is also reasonable on Oracle's part IMO.
update
( select t1.aff_id, t2.cust_aff_id
from affiliation t1 join customer t2 on t2.cust_id = t1.from_cus_id) j
set j.cust_aff_id = j.aff_id;
Can someone please help me to solve this .. I need to write oracle query to sum up the balances by by REF and REFERENCE_ID
Below are some criteria,
MultiValue can start with 1, 2, 3 and it will have any number of Subvalues from 1 to n...
Now PROPERTY field value is available only for MultiValue=1 and SubValue=1..
we have consider same PROPERTY property field for that multivalue set.
e.g for MultiValue 1 PROPERTY=BALANCE and Multivalue =2 PROPERTY = INTEREST etc...and need to sum up the balances
by REF and REFERENC_ID
Also, need to separate BALANCES amouts and INTEREST amount and PENALTY amount.
Here is some sample data... Any help is appreciated.. Thanks in advance.
Here is the sample output for first two ids..
You can fill in the missing propery values with an analytic first_value() function call (or max, min, etc.):
select reference_id, multivalue, subvalue, code,
first_value(property) over (partition by reference_id, multivalue) as property,
ref, amount
from your_table;
REFERENCE_ID MULTIVALUE SUBVALUE CODE PROPERTY R AMOUNT
-------------- ---------- ---------- ---------- -------- - ----------
BILL121220PBD8 1 1 10001 BALANCE a 1061.08
BILL121220PBD8 1 2 10001 BALANCE b 5395.89
BILL121220PBD8 1 3 10001 BALANCE c 4043.07
BILL121220PBD8 1 4 10001 BALANCE d 4100.22
BILL121220R2HL 2 1 10001 INTEREST e 60487.88
BILL121220R2HL 2 2 10001 INTEREST e 60487.88
BILL121220R2HL 2 3 10001 INTEREST f 526631.51
...
Then you can use that as a subquery (as an inline view or CTE) to form the basis for your grouping:
select reference_id as bill_reference, property, ref as repay_ref,
sum(amount) as repay_amount
from (
select reference_id, multivalue, subvalue, code,
first_value(property) over (partition by reference_id, multivalue) as property,
ref, amount
from your_table
)
group by reference_id, property, ref
order by reference_id, property, ref;
BILL_REFERENCE PROPERTY R REPAY_AMOUNT
-------------- -------- - ------------
BILL121220PBD8 BALANCE a 1061.08
BILL121220PBD8 BALANCE b 5395.89
BILL121220PBD8 BALANCE c 4043.07
BILL121220PBD8 BALANCE d 4100.22
BILL121220R2HL INTEREST e 120975.76
BILL121220R2HL INTEREST f 526631.51
...
(I retyped the reference IDs from your image to make up the test data, but couldn't be bothered to retype the individual ref's too. One of the reasons it's preferred to have text in questions rather than images.)
Are you trying to aggregate the amount by REF or REFERENCE_ID? If so, you should use group by clause.
For example, if you want to sum up the amount for each type of REF:
select REF, SUM(AMOUNT)
from BALANCE_TBL
group by REF
On a new job I have to figure out how some database reporting scripts are working.
There is one table that is giving me some trouble. I see in existing scripts that it is a partitioned table.
My problem is that whatever query I run on this table returns me "no rows selected".
Here are some details about my investigation in this table:
Table size estimate
SQL> select sum(bytes)/1024/1024 Megabytes from dba_segments where segment_name = 'PPREC';
MEGABYTES
----------
45.625
Partitions
There are a total of 730 partitions on date range.
SQL> select min(PARTITION_NAME),max(PARTITION_NAME) from dba_segments where segment_name = 'PPREC';
MIN(PARTITION_NAME) MAX(PARTITION_NAME)
------------------------------ ------------------------------
PART20110201 PART20130130
There are several tablespaces and partitions are allocated in them
SQL> select tablespace_name, count(partition_name) from dba_segments where segment_name = 'PPREC' group by tablespace_name;
TABLESPACE_NAME COUNT(PARTITION_NAME)
------------------------------ ---------------------
REC_DATA_01 281
REC_DATA_02 48
REC_DATA_03 70
REC_DATA_04 26
REC_DATA_05 44
REC_DATA_06 51
REC_DATA_07 13
REC_DATA_08 48
REC_DATA_09 32
REC_DATA_10 52
REC_DATA_11 35
REC_DATA_12 30
Additional query:
SQL> select * from dba_segments where segment_name='PPREC' and partition_name='PART20120912';
OWNER SEGMENT_NAME PARTITION_NAME SEGMENT_TYPE TABLESPACE_NAME HEADER_FILE HEADER_BLOCK BYTES BLOCKS EXTENTS
----- ------------ -------------- --------------- --------------- ----------- ------------ ----- ------ -------
HIST PPREC PART20120912 TABLE PARTITION REC_DATA_01 13 475315 65536 8 1
INITIAL_EXTENT NEXT_EXTENT MIN_EXTENTS MAX_EXTENTS PCT_INCREASE FREELISTS FREELIST_GROUPS RELATIVE_FNO BUFFER_POOL
-------------- ----------- ----------- ----------- ------------ --------- --------------- ------------ -----------
65536 1 2147483645 13 DEFAULT
Tabespace usage
Here is a space summary (composite of dba_tablespaces, dba_data_files, dba_segments, dba_free_space)
TABLESPACE_NAME TOTAL_MEGABYTES USED_MEGABYTES FREE_MEGABYTES
------------------------------ --------------- -------------- --------------
REC_01_INDX 30,700 250 30,449
REC_02_INDX 7,745 7 7,737
REC_03_INDX 22,692 15 22,677
REC_04_INDX 15,768 10 15,758
REC_05_INDX 25,884 16 25,868
REC_06_INDX 27,992 16 27,975
REC_07_INDX 17,600 10 17,590
REC_08_INDX 18,864 11 18,853
REC_09_INDX 19,700 12 19,687
REC_10_INDX 28,716 16 28,699
REC_DATA_01 102,718 561 102,156
REC_DATA_02 24,544 3,140 21,403
REC_DATA_03 72,710 4 72,704
REC_DATA_04 29,191 2 29,188
REC_DATA_05 42,696 3 42,692
REC_DATA_06 52,780 323 52,456
REC_DATA_07 16,536 1 16,534
REC_DATA_08 49,247 3 49,243
REC_DATA_09 30,848 2 30,845
REC_DATA_10 49,620 3 49,616
REC_DATA_11 40,616 2 40,613
REC_DATA_12 184,922 123,435 61,486
The tablespace usage seems to confirm that this table is not empty, in fact its last tablespace (REC_DATA_12) seems pretty busy.
Existing scripts
What I find puzzling is that there are some PL/SQL stored procedures that seem to work on that table and get data out of it.
An example of such a stored procedure is as follows:
procedure FIRST_REC as
vpartition varchar2(12);
begin
select 'PART'||To_char(sysdate,'YYYYMMDD') INTO vpartition FROM DUAL;
execute immediate
'MERGE INTO FIRST_REC_temp a
USING (SELECT bno, min(trdate) mintr,max(trdate) maxtr
FROM PPREC PARTITION ('||vpartition||') WHERE route_id IS NOT NULL AND trunc(trdate) <= trunc(sysdate-1)
GROUP BY bno) b
ON (a.bno=b.bno)
when matched then
update set a.last_tr = b.maxtr
when not matched then
insert (a.bno,a.last_tr,a.first_tr)
values (b.bno,b.maxtr,b.mintr)';
commit;
However if I try using the same syntax manually on the table, here is what I get:
SQL> select count(*) from PPREC PARTITION (PART20120912);
COUNT(*)
----------
0
I have tried a few random partitions and I always get the same 0 count.
Summary
- I see a table that seems to contain data (space used, tablespaces, data files)
- The table is partitioned (one partition per day over a period of 730 days ending end of January 2013)
- Scripts are extracting data from that table somehow
Question
- My queries using PARTITION are all returning me "no rows selected". What am I doing wrong? How could I find out how to extract data from this table?
I suppose it's possible that some other process might be deleting the data, but without visiting your site there's no way for anyone here to tell if that might be so.
I don't see in your post that you mentioned the name of the partitioning DATE column, but based on the SQL you posted I'll assume it's TRDATE - if this is not correct, change TRDATE in the statement below to be the partitioning column.
That said, give this a try:
SELECT COUNT(*)
FROM PPREC
WHERE TRDATE >= TO_DATE('01-SEP-2012 00:00:00', 'DD-MON-YYYY HH24:MI:SS')
This assumes you should have data in this table from September. If you find data, great. If you don't - well, Back In The Day (when men were men, women were women, and computers were water-cooled :-) we had a little saying about memory on IBM mainframes:
1. If you can see it, and it's there, it's Real.
2. If you can't see it, but it's there, it's Protected.
3. If you can see it, but it's not there, it's Virtual.
4. If you can't see it, and it's not there, it's GONE!
:-)
Use of the PARTITION clause should be reserved for situations where you are experiencing a performance problem (note: guessing about what is or is not going to be a performance problem is not allowed. Until you've got a performance problem you don't have a performance problem. Over the years I've found that software spends a lot of execution time in the darndest places :-), and the usual fixes (adding indexes, deleting unnecessary data, human sacrifice, etc) haven't worked. Basically, write your queries normally and trust the database to get it right. (In the general case - always write the simplest code - and do the simplest thing - that could possibly work. 99+ percent of the time it will be fine. That allows you to spend your optimization time on the less-than-one-percent cases where simple isn't good enough - and most of the software you write or design will be simple and easy to understand).
Share and enjoy.