the compute functions results are not visible. only total and count are visible
BREAK ON PET_ID SKIP 5
COMPUTE COUNT LABEL 'No. of Visits' OF VISIT_DATE ON PET_ID
COMPUTE AVG LABEL 'Avg Cost' OF BASIC_COST ON PET_ID
COMPUTE MIN LABEL 'Min Cost' OF BASIC_COST ON PET_ID
COMPUTE MAX LABEL 'Max Cost' OF BASIC_COST ON PET_ID
COMPUTE SUM LABEL 'Total Cost' OF BASIC_COST ON PET_ID
/
Don't use COMPUTE as separate commands (because only the last takes effect); put all of them into the single line, separated by space.
SQL> break on pet_id
SQL> compute count label 'No. of visits' avg label 'avg cost' min label 'min cost' max label 'max cost' sum label 'total cost' of basic_cost on pet_id
SQL> select * from pets order by pet_id;
PET_ID PET_NAME BASIC_COST
---------- ---------- ----------
10 CLARK 2450
KING 5000
MILLER 1300
********** ----------
avg cost 2916,66667
No. of vis 3
min cost 1300
max cost 5000
total cost 8750
20 JONES 2975
FORD 3000
PET_ID PET_NAME BASIC_COST
---------- ---------- ----------
20 ADAMS 1100
SMITH 800
SCOTT 3000
********** ----------
avg cost 2175
No. of vis 5
min cost 800
max cost 3000
total cost 10875
30 WARD 1250
TURNER 1500
PET_ID PET_NAME BASIC_COST
---------- ---------- ----------
30 ALLEN 1600
JAMES 950
BLAKE 2850
MARTIN 1250
********** ----------
avg cost 1566,66667
No. of vis 6
min cost 950
max cost 2850
total cost 9400
14 rows selected.
SQL>
Related
I have a situation where I want to update the value of one column using column values from the same table and another table, and also update based on the account value - which changes. I think this might need Lead or Lag, and I tried MERGE. Or maybe a complicated UPDATE statement? Thank you in advance!
Table WRK
Name ID Date1 PROJ Date2 Account Amt1 Amt2 Amt3
Smith 12345 4-JUL-2020 50 30-JUL-2021 312001 2 4 6
Smith 12345 4-JUL-2020 60 30-JUL-2021 312002 6 8 10
Smith 12345 4-JUL-2020 91 30-JUL-2021 412901 2 4 6
Jones 02468 5-JUL-2020 70 30-JUL-2021 312001 4 8 10
Jones 02468 5-JUL-2020 80 30-JUL-2021 312002 4 8 10
Jones 02468 5-JUL-2020 91 30-JUL-2021 412901 4 8 10
Table Combined
Name ID Date1 PROJ Date2 Account Combine amt
Smith 12345 4-JUL-2020 50 30-JUL-2021 312001 3
Smith 12345 4-JUL-2020 60 30-JUL-2021 312002 6
Smith 12345 4-JUL-2020 91 30-JUL-2021 412901 9
Jones 02468 5-JUL-2020 70 30-JUL-2021 312001 22
Jones 02468 5-JUL-2020 80 30-JUL-2021 312002 10
Jones 02468 5-JUL-2020 91 30-JUL-2021 412901 5
Essentially, I want the Combine amount from Combine table for account = 412901 entry to be used to update WRK table Amt1 for the account = 312001/312002 entries when matched in WRK and COMBINE for the same ID, Date1 and Date2 and PROJ
• Compute WRK.Amt1 = (value of Combine amt for account %901 – value of WRK account 312001 WRK.Amt1) * value of WRK account 312001 WRK.Amt2 / value of WRK account 312001 WRK.Amt3
• Compute WRK.Amt1 = (value of Combine amt for account %901 – value of WRK account 312002 WRK.Amt1) * value of WRK account 312002 WRK.Amt2 / value of WRK account 312001 WRK.Amt3
So when working, I would expect WRK Amt1 for Smith (12345) account 312001, Date1 = 4-JUL-2020, Date2 =30-JUL-2021 to be = 4.6666:
• Use Combine amt from Combine table for 412901 for 12345 4-JUL-2020 and 30-JUL-2021 (‘9’) – Amt1 for 312001 for 12345 4-JUL-2020 and 30-JUL-2021 (‘2’) * Amt2 (‘4’) / Amt 3 (‘6’)
• 9 – 2 * 4/6 = 4.6666
…and Amt1 for Smith (12345) account 312002, Date1 = 4-JUL-2020, Date2 =30-JUL-2021 AMT1 to be = 2.4:
• Use Combine amt from Combine table for 412901 for 12345 4-JUL-2020 and 30-JUL-2021 (‘9’) – Amt1 for 312002 for 12345 4-JUL-2020 and 30-JUL-2021 (‘6’) * Amt2 (‘8’) / Amt 3 (‘10’)
9 – 6 * 8/10 = 2.4
I used a Merge statement, but it did not affect AMT1 :**
MERGE INTO WRK W USING (SELECT DISTINCT ID,
DATE1,
DATE2,
ACCOUNT,
PROJ,
COMBINE_AMT
FROM COMBINED) C
ON ( C.ID = W.ID
AND C.DATE1 = W.DATE1
AND C.DATE2 = W.DATE2
AND C.PROJ = W.PROJ
AND ( (SUBSTR (C.ACCOUNT, 4, 3) = '901')
OR (SUBSTR (C.ACCOUNT, 5, 2) = '98')))
WHEN MATCHED
THEN
UPDATE SET
W.AMT1 = ROUND((C.COMBINE_AMT - W.AMT1) * (W.AM2 / W.AMT3), 2)
WHERE SUBSTR (W.ACCOUNT, 1, 2) = '31'
AND ( (SUBSTR (W.ACCOUNT, 4, 3) <> '901')
AND (SUBSTR (W.ACCOUNT, 5, 2) <> '98'))
We have this data : Table R(A,..) with attribute A, nbLine of R is 1000, distinct value for A are 500.
data are displayed like this : bucket -> end_point_value.
1 -> 800
2 -> 900
3 -> 1000
4 -> 1200
5 -> 1500
6 -> 2000
7 -> 2300
8 -> 2400
9 -> 2550
10 -> 2590
the question is : Does this histogram confirm or deny the hypothesis of a uniform distribution uniform?
I think I can not confirm nor deny, what do you think ?
First you must ask, which histogram type is defined on the column.
Oracle provides four different histogram types and is you want to claim about uniform distribution the frequency histogram must be defined.
The frequency histogram has one bucket for each distinct value (stored in ENDPOINT_VALUE and the frequency is (additive) stored in the column ENDPOINT_NUMBER)
So if you histogram has only 10 buckets (as you show in the data) you are ready and you can say nothing about the distribution.
Example of a Uniform Distribution
create table r as
select
1 + trunc((rownum-1)/2) A
from dual connect by level <= 1000;
select count(*), count(distinct a), min(a), max(a) from r;
COUNT(*) COUNT(DISTINCTA) MIN(A) MAX(A)
---------- ---------------- ---------- ----------
1000 500 1 500
Create FREQUENCY Histogram with 500 Buckets
exec dbms_stats.gather_table_stats(ownname=>user, tabname=>'R', method_opt=>'for all columns size 500');
select NUM_BUCKETS, HISTOGRAM from user_tab_columns where table_name = 'R';
NUM_BUCKETS HISTOGRAM
----------- ---------------
500 FREQUENCY
select ENDPOINT_VALUE, ENDPOINT_NUMBER from user_histograms where table_name = 'R' order by ENDPOINT_VALUE;
ENDPOINT_VALUE, ENDPOINT_NUMBER
1 2
2 4
3 6
4 8
...
498 996
499 998
500 1000
How can I list Oracle all tablespaces +temp Tablespace by displaying
allocate space(MB), used space(MB), status(online\offline) and type with one SQL query?
Something like this?
SQL> set pagesize 100
SQL> set linesize 100
SQL> break on tablespace_name on status on total_mb
SQL> compute sum of used_mb on tablespace_name
SQL> WITH total
2 AS ( SELECT f.tablespace_name,
3 ROUND (SUM (f.bytes) / POWER (2, 20)) total_mb
4 FROM dba_data_files f
5 GROUP BY f.tablespace_name),
6 used
7 AS ( SELECT s.tablespace_name,
8 s.segment_type,
9 ROUND (SUM (s.bytes) / POWER (2, 20)) used_mb
10 FROM dba_segments s
11 GROUP BY s.tablespace_name, s.segment_type)
12 SELECT ts.tablespace_name,
13 ts.status,
14 t.total_mb,
15 u.segment_type,
16 u.used_mb
17 FROM dba_tablespaces ts
18 JOIN total t ON t.tablespace_name = ts.tablespace_name
19 JOIN used u ON u.tablespace_name = ts.tablespace_name
20 ORDER BY ts.tablespace_name, u.segment_type;
TABLESPACE_NAME STATUS TOTAL_MB SEGMENT_TYPE USED_MB
------------------------------ --------- ---------- ------------------ ----------
APEX ONLINE 544 INDEX 150
LOBINDEX 8
LOBSEGMENT 157
TABLE 179
****************************** ********* ********** ----------
sum 494
APEX_9695076087226093 ONLINE 200 INDEX 1
LOBINDEX 0
LOBSEGMENT 0
TABLE 1
****************************** ********* ********** ----------
sum 2
SYSAUX ONLINE 9816 CLUSTER 3
INDEX 565
INDEX PARTITION 3198
LOB PARTITION 0
LOBINDEX 46
LOBSEGMENT 727
NESTED TABLE 3
TABLE 643
TABLE PARTITION 4017
TABLE SUBPARTITION 2
****************************** ********* ********** ----------
sum 9204
SYSTEM ONLINE 1724 CLUSTER 68
INDEX 184
LOBINDEX 7
LOBSEGMENT 16
NESTED TABLE 1
ROLLBACK 0
TABLE 813
****************************** ********* ********** ----------
sum 1089
UNDOTBS1 ONLINE 4608 TYPE2 UNDO 144
****************************** ********* ********** ----------
sum 144
USER_DATA ONLINE 38820 INDEX 5335
LOBINDEX 40
LOBSEGMENT 9168
TABLE 18104
****************************** ********* ********** ----------
sum 32647
30 rows selected.
SQL>
I have a table (MyTable) with this columns:
point
alarm
load_id
countAlarms
...
and I use this query:
select point, decode(alarm,0,'new','rec') NewRec, sum (countAlarms) total_alarms, load_id from MyTable
where 1=1
--and load_id = (select max(load_id) from MyTable ) -0
group by point, decode(alarm,0,'new','rec'), load_id
order by 1, 2
)
to receive something like this:
point1 new 1200 111113
point1 rec 6000 111113
point2 new 1220 111113
point2 rec 3000 111113
point3 new 3220 111113
point3 rec 1000 111113
point1 new 1300 111112
point1 rec 6300 111112
point3 new 1220 111112
point3 rec 1100 111112
point1 new 1300 111111
point1 rec 6300 111111
point2 new 1120 111111
point2 rec 3100 111111
point3 new 1220 111111
point3 rec 1100 111111
....
what i need is this:
point newRec point point point
---------------------------------------
point1 new 1200 1300 1300
point1 rec 6000 6300 6300
point2 new 1220 1120
point2 rec 3000 3100
point3 new 3220 1220 1220
point3 rec 1000 1100 1100
I have tried with a full outer join but it don't work :(
It looks like you want to pivot your result set, rather than join it to itself. Assuming you're on Oracle 11g or higher you can do this natively:
select * from (
select point, decode(alarm,0,'new','rec') NewRec, countAlarms, load_id
from MyTable
)
pivot (
sum(countAlarms) as alarms
for (load_id) in (111113 as a, 111112 as b, 111111 as c)
)
order by 1, 2;
Which with sample data matching your output above gives:
POINT NEWREC A_ALARMS B_ALARMS C_ALARMS
------ ------ ---------- ---------- ----------
point1 new 1200 1300 1300
point1 rec 6000 6300 6300
point2 new 1220 1120
point2 rec 3000 3100
point3 new 3220 1220 1220
point3 rec 1000 1100 1100
SQL Fiddle demo.
You have to know the values you're pivoting on though; it isn't clear if you know the load IDs in advance, but the commented-out load ID filter in your original query suggests you might not. If you always want the three (or any fixed number of) highest load IDs then that can be achieved by modifying the inner query and the pivot criteria, e.g. with an analytic dense_rank() pseudo-column:
select * from (
select point, decode(alarm,0,'new','rec') NewRec, countAlarms,
dense_rank() over (partition by null order by load_id desc) as rnk
from MyTable
)
pivot (
sum(countAlarms) as alarms
for (rnk) in (1 as a, 2 as b, 3 as c)
)
order by 1, 2;
SQL Fiddle.
First off, I'm a total Oracle noob although I'm very familiar with SQL. I have a single cost column. I need to calculate the total cost, the percentage of the total cost, and then a running sum of the percentages. I'm having trouble with the running sum of percentages because the only way I can think to do this uses nested SUM functions, which isn't allowed.
Here's what works:
SELECT cost, SUM(cost) OVER() AS total, cost / SUM(cost) OVER() AS per
FROM my_table
ORDER BY cost DESC
Here's what I'm trying to do that doesn't work:
SELECT cost, SUM(cost) OVER() AS total, cost / SUM(cost) OVER() AS per,
SUM(cost/SUM(cost) OVER()) OVER(cost) AS per_sum
FROM my_table
ORDER BY cost DESC
Am I just going about it wrong, or is what I'm trying to do just not possible? By the way I'm using Oracle 10g. Thanks in advance for any help.
You don't need the order by inside that inline view, especially since the outer select is doing an order by the order way around. Also, cost / SUM(cost) OVER () equals RATIO_TO_REPORT(cost) OVER ().
An example:
SQL> create table my_table(cost)
2 as
3 select 10 from dual union all
4 select 20 from dual union all
5 select 5 from dual union all
6 select 50 from dual union all
7 select 60 from dual union all
8 select 40 from dual union all
9 select 15 from dual
10 /
Table created.
Your initial query:
SQL> SELECT cost, SUM(cost) OVER() AS total, cost / SUM(cost) OVER() AS per
2 FROM my_table
3 ORDER BY cost DESC
4 /
COST TOTAL PER
---------- ---------- ----------
60 200 .3
50 200 .25
40 200 .2
20 200 .1
15 200 .075
10 200 .05
5 200 .025
7 rows selected.
Quassnoi's query contains a typo:
SQL> SELECT cost, total, per, SUM(running) OVER (ORDER BY cost)
2 FROM (
3 SELECT cost, SUM(cost) OVER() AS total, cost / SUM(cost) OVER() AS per
4 FROM my_table
5 ORDER BY
6 cost DESC
7 )
8 /
SELECT cost, total, per, SUM(running) OVER (ORDER BY cost)
*
ERROR at line 1:
ORA-00904: "RUNNING": invalid identifier
And if I correct that typo. It gives the right results, but wrongly sorted (I guess):
SQL> SELECT cost, total, per, SUM(per) OVER (ORDER BY cost)
2 FROM (
3 SELECT cost, SUM(cost) OVER() AS total, cost / SUM(cost) OVER() AS per
4 FROM my_table
5 ORDER BY
6 cost DESC
7 )
8 /
COST TOTAL PER SUM(PER)OVER(ORDERBYCOST)
---------- ---------- ---------- -------------------------
5 200 .025 .025
10 200 .05 .075
15 200 .075 .15
20 200 .1 .25
40 200 .2 .45
50 200 .25 .7
60 200 .3 1
7 rows selected.
I think this is the one you are looking for:
SQL> select cost
2 , total
3 , per
4 , sum(per) over (order by cost desc)
5 from ( select cost
6 , sum(cost) over () total
7 , ratio_to_report(cost) over () per
8 from my_table
9 )
10 order by cost desc
11 /
COST TOTAL PER SUM(PER)OVER(ORDERBYCOSTDESC)
---------- ---------- ---------- -----------------------------
60 200 .3 .3
50 200 .25 .55
40 200 .2 .75
20 200 .1 .85
15 200 .075 .925
10 200 .05 .975
5 200 .025 1
7 rows selected.
Regards,
Rob.
SELECT cost, total, per, SUM(per) OVER (ORDER BY cost)
FROM (
SELECT cost, SUM(cost) OVER() AS total, cost / SUM(cost) OVER() AS per
FROM my_table
)
ORDER BY
cost DESC