Analytic function for grouping?
Hello @all
10gR2
Is it possible to use an analytic function for grouping following (example-)query:
SELECT job, ename, sal,
ROW_NUMBER() OVER(PARTITION BY job ORDER BY empno) AS no,
RANK() OVER(PARTITION BY job ORDER BY NULL) AS JobNo
FROM emp;The output is following:
JOB ENAME SAL NO JOBNO
ANALYST SCOTT 3000 1 1
ANALYST FORD 3000 2 1
CLERK SMITH 818 1 1
CLERK ADAMS 1100 2 1
CLERK JAMES 950 3 1
CLERK MILLER 1300 4 1
MANAGER Müller 1000 1 1
MANAGER JONES 2975 2 1
....The JobNo should increase group by job and ename; my desired output should be looking like...:
JOB ENAME SAL NO JOBNO
ANALYST SCOTT 3000 1 1
ANALYST FORD 3000 2 1
CLERK SMITH 818 1 2
CLERK ADAMS 1100 2 2
CLERK JAMES 950 3 2
CLERK MILLER 1300 4 2
MANAGER Müller 1000 1 3
MANAGER JONES 2975 2 3
MANAGER BLAKE 2850 3 3
MANAGER CLARK 2450 4 3
PRESIDENT KING 5000 1 4
SALESMAN ALLEN 1600 1 5
SALESMAN WARD 1250 2 5
SALESMAN MARTIN 1250 3 5
SALESMAN TURNER 1500 4 5How can I achieve this?
This, perhaps?
with emp as (select 1 empno, 'ANALYST' job, 'SCOTT' ename, 3000 sal from dual union all
select 2 empno, 'ANALYST' job, 'FORD' ename, 3000 sal from dual union all
select 3 empno, 'CLERK' job, 'SMITH' ename, 818 sal from dual union all
select 4 empno, 'CLERK' job, 'ADAMS' ename, 1100 sal from dual union all
select 5 empno, 'CLERK' job, 'JAMES' ename, 950 sal from dual union all
select 6 empno, 'CLERK' job, 'MILLER' ename, 1300 sal from dual union all
select 7 empno, 'MANAGER' job, 'Müller' ename, 1000 sal from dual union all
select 8 empno, 'MANAGER' job, 'JONES' ename, 2975 sal from dual union all
select 9 empno, 'MANAGER' job, 'BLAKE' ename, 2850 sal from dual union all
select 10 empno, 'MANAGER' job, 'CLARK' ename, 2450 sal from dual union all
select 11 empno, 'PRESIDENT' job, 'KING' ename, 5000 sal from dual union all
select 12 empno, 'SALESMAN' job, 'ALLEN' ename, 1600 sal from dual union all
select 13 empno, 'SALESMAN' job, 'WARD' ename, 1250 sal from dual union all
select 14 empno, 'SALESMAN' job, 'MARTIN' ename, 1250 sal from dual union all
select 15 empno, 'SALESMAN' job, 'TURNER' ename, 1500 sal from dual)
select job, ename, sal,
row_number() over(partition by job order by empno) no,
dense_rank() over(order by job) jobno
from emp
JOB ENAME SAL NO JOBNO
ANALYST SCOTT 3000 1 1
ANALYST FORD 3000 2 1
CLERK SMITH 818 1 2
CLERK ADAMS 1100 2 2
CLERK JAMES 950 3 2
CLERK MILLER 1300 4 2
MANAGER Müller 1000 1 3
MANAGER JONES 2975 2 3
MANAGER BLAKE 2850 3 3
MANAGER CLARK 2450 4 3
PRESIDENT KING 5000 1 4
SALESMAN ALLEN 1600 1 5
SALESMAN WARD 1250 2 5
SALESMAN MARTIN 1250 3 5
SALESMAN TURNER 1500 4 5
Similar Messages
-
Analytic Functions with GROUP-BY Clause?
I'm just getting acquainted with analytical functions. I like them. I'm having a problem, though. I want to sum up the results, but either I'm running into a limitation or I'm writing the SQL wrong. Any hints for me?
Hypothetical Table SALES consisting of a DAY_ID, PRODUCT_ID, PURCHASER_ID, PURCHASE_PRICE lists all the
Hypothetical Business Question: Product prices can fluctuate over the course of a day. I want to know how much per day I would have made had I sold one each of all my products at their max price for that day. Silly question, I know, but it's the best I could come up with to show the problem.
INSERT INTO SALES VALUES(1,1,1,1.0);
INSERT INTO SALES VALUES(1,1,1,2.0);
INSERT INTO SALES VALUES(1,2,1,3.0);
INSERT INTO SALES VALUES(1,2,1,4.0);
INSERT INTO SALES VALUES(2,1,1,5.0);
INSERT INTO SALES VALUES(2,1,1,6.0);
INSERT INTO SALES VALUES(2,2,1,7.0);
INSERT INTO SALES VALUES(2,2,1,8.0);
COMMIT;
Day 1: Iif I had sold one product 1 at $2 and one product 2 at $4, I would have made 6$.
Day 2: Iif I had sold one product 1 at $6 and one product 2 at $8, I would have made 14$.
The desired result set is:
DAY_ID MY_MEASURE
1 6
1 14The following SQL gets me tantalizingly close:
SELECT DAY_ID,
MAX(PURCHASE_PRICE)
KEEP(DENSE_RANK FIRST ORDER BY PURCHASE_PRICE DESC)
OVER(PARTITION BY DAY_ID, PRODUCT_ID) AS MY_MEASURE
FROM SALES
ORDER BY DAY_ID
DAY_ID MY_MEASURE
1 2
1 2
1 4
1 4
2 6
2 6
2 8
2 8But as you can see, my result set is "longer" than I wanted it to be. I want a single row per DAY_ID. I understand what the analytical functions are doing here, and I acknowledge that I am "not doing it right." I just can't seem to figure out how to make it work.
Trying to do a sum() of max() simply does not work, nor does any semblance of a group-by clause that I can come up with. Unfortunately, as soon as I add the windowing function, I am no longer allowed to use group-by expressions (I think).
I am using a reporting tool, so unfortunately using things like inline views are not an option. I need to be able to define "MY_MEASURE" as something the query tool can apply the SUM() function to in its generated SQL.
(Note: The actual problem is slightly less easy to conceptualize, but solving this conundrum will take me much closer to solving the other.)
I humbly solicit your collective wisdom, oh forum.Thanks, SY. I went that way originally too. Unfortunately that's no different from what I could get without the RANK function.
SELECT DAY_ID,
PRODUCT_ID,
MAX(PURCHASE_PRICE) MAX_PRICE
FROM SALES
GROUP BY DAY_ID,
PRODUCT_ID
ORDER BY DAY_ID,
PRODUCT_ID
DAY_ID PRODUCT_ID MAX_PRICE
1 1 2
1 2 4
2 1 6
2 2 8 -
Disco -- Any analytical functions for comparisons
Hi:
I'm wondering if there are any analytical function to help me out with comparisons? Users often need to displays totals based on date ranges, and show the difference between the two totals, as well as percent change.
For example, a workbook would show the comparison of cases and dollars, for 2002 vs. 2003. Currently, my solution for this is to create DECODE calculations based on year and type (cases or dollars), and perform the
comparisons in separate calculations. I'd like to know if Discoverer already has a function that would handle some of this, and reduce the number of DECODES and separate calculations the users have to create...
Thanks,
Subramanyam
Sr. Technical Consultant
Oracle DirectHello
You can use the Oracle database SQL analytic function to perform comparison and window based calculations. Example: LAG, LEAD, RANK, etc...
Please consult the Oracle 9.2 database documentation as well as Discoverer documentation for examples and syntax.
Regards
Discoverer Product Management -
How to use Pivot function for group range in oracle SQL
Hi,
Good Morning !!!
I need to show the data in the below format. There is 2 columns 1 is State and another one is rate.
State <100 100-199 200-299 300-399 400-499 500-599 600-699 700-799 800-899 900-999 >=1000 Total
AK 1 2 0 4 1 4 4 35 35 4 1 25
AL 0 0 2 27 10 17 35 2 2 35 0 103
AR 0 0 1 0 0 2 2 13 13 2 0 6
AZ 0 1 2 14 2 14 13 3 3 13 0 57
CA 0 0 1 6 2 7 3 4 4 3 0 34
Developed the below query but unable to use the range on pivot function . Please help on this.
(select (SELECT SHORT_DESCRIPTION
FROM CODE_VALUES
WHERE CODE_TYPE_CODE = ad.STATE_TYPE_IND_CODE
AND VALUE = ad.STATE_CODE
) STATE,
nr.rate
FROM neutrals n,
contacts c,
addresses ad,
xref_contacts_addresses xca,
neutral_rates nr
where n.contact_id=c.contact_id
and n.address_id = ad.address_id
and xca.address_id=ad.address_id
and xca.contact_id=c.contact_id
and nr.contact_id = n.contact_id
and nr.rate_frequency='HOUR' )user8564931 wrote:
This solutions is useful and Thanks for your reply.
How can i get the Min value and Max value for each row ?
State <100 100-199 200-299 300-399 400-499 500-599 600-699 700-799 800-899 900-999 >=1000 Total Min Max
IL 0 0 1 5 1 5 40 1 1 40 0 53 $10 $2,500
IN 0 0 0 0 0 0 1 49 49 1 0 3 $70 $1,500This?
WITH t AS
(SELECT 'AL' state, 12 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 67 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 23 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 12 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 12 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 78 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 34 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 4 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 12 VALUE FROM DUAL
UNION ALL
SELECT 'AL' state, 15 VALUE FROM DUAL
UNION ALL
SELECT 'AZ' state, 6 VALUE FROM DUAL
UNION ALL
SELECT 'AZ' state, 123 VALUE FROM DUAL
UNION ALL
SELECT 'AZ' state, 123 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 23 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 120 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 456 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 11 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 24 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 34 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 87 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 23 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 234 VALUE FROM DUAL
UNION ALL
SELECT 'MA' state, 789 VALUE FROM DUAL
UNION ALL
SELECT 'MH' state, 54321 VALUE FROM DUAL),
-- End of test data
t1 AS
( SELECT state,
NVL (COUNT (DECODE (VALUE, 0, 0)), 0) "<100",
NVL (COUNT (DECODE (VALUE, 1, 1)), 0) "100-199",
NVL (COUNT (DECODE (VALUE, 2, 2)), 0) "200-299",
NVL (COUNT (DECODE (VALUE, 3, 3)), 0) "300-399",
NVL (COUNT (DECODE (VALUE, 4, 4)), 0) "400-499",
NVL (COUNT (DECODE (VALUE, 5, 5)), 0) "500-599",
NVL (COUNT (DECODE (VALUE, 6, 6)), 0) "600-699",
NVL (COUNT (DECODE (VALUE, 7, 7)), 0) "700-799",
NVL (COUNT (DECODE (VALUE, 8, 8)), 0) "800-899",
NVL (COUNT (DECODE (VALUE, 9, 9)), 0) "900-999",
NVL (COUNT (DECODE (VALUE, 10, 10)), 0) ">=1000"
FROM (SELECT state,
CASE
WHEN VALUE < 100 THEN 0
WHEN VALUE BETWEEN 100 AND 199 THEN 1
WHEN VALUE BETWEEN 200 AND 299 THEN 2
WHEN VALUE BETWEEN 300 AND 399 THEN 3
WHEN VALUE BETWEEN 400 AND 499 THEN 4
WHEN VALUE BETWEEN 500 AND 599 THEN 5
WHEN VALUE BETWEEN 600 AND 699 THEN 6
WHEN VALUE BETWEEN 700 AND 799 THEN 7
WHEN VALUE BETWEEN 800 AND 899 THEN 8
WHEN VALUE BETWEEN 900 AND 999 THEN 9
WHEN VALUE >= 1000 THEN 10
END
VALUE
FROM t)
GROUP BY state)
SELECT STATE,
"<100",
"100-199",
"200-299",
"300-399",
"400-499",
"500-599",
"600-699",
"700-799",
"800-899",
"900-999",
">=1000",
"<100"
+ "100-199"
+ "200-299"
+ "300-399"
+ "400-499"
+ "500-599"
+ "600-699"
+ "700-799"
+ "800-899"
+ "900-999"
+ ">=1000"
total,
least("<100",
"100-199",
"200-299",
"300-399",
"400-499",
"500-599",
"600-699",
"700-799",
"800-899",
"900-999",
">=1000") min_val,
greatest("<100",
"100-199",
"200-299",
"300-399",
"400-499",
"500-599",
"600-699",
"700-799",
"800-899",
"900-999",
">=1000") max_val
FROM t1
/ -
Analytic function with GROUP BY
Hi:
using the query below I am getting the following error --> 3:19:15 PM ORA-00979: not a GROUP BY expression
SELECT a.proj_title_ds, b.prgm_sers_title_nm,
SUM(c.PRGM_TOT_EXP_AMT) OVER(PARTITION BY c.prgm_id) AS "Total $ Spend1"
FROM iPlanrpt.VM_RPT_PROJECT a INNER JOIN iPlanrpt.VM_RPT_PRGM_SERS b
ON a.proj_id = b.proj_id INNER JOIN iPlanrpt.VM_RPT_PRGM c
ON b.prgm_sers_id = c.prgm_sers_id
WHERE a.proj_id IN (1209624,1209623,1209625, 1211122,1211123)
AND c.PRGM_STATE_ID in (6,7)
GROUP BY a.proj_title_ds, b.prgm_sers_title_nm
Any suggestions to get the desired result (Sum of c.PRGM_TOT_EXP_AMT for each / distinct c.prgm_id within the group by specified) will be helpful@OP,
Please mark the "other duplicate thread as complete or duplicate". I responded to the other thread and asked to sample data.
With the sample included here...would the following work for you?
SELECT a.proj_title_ds,
b.prgm_sers_title_nm,
SUM (c.prgm_tot_exp_amt) AS "Total $ Spend1"
FROM iplanrpt.vm_rpt_project a
INNER JOIN
iplanrpt.vm_rpt_prgm_sers b
ON a.proj_id = b.proj_id
INNER JOIN
(select distinct prgm_id, prgm_tot_exp_amt from iplanrpt.vm_rpt_prgm ) c
ON b.prgm_sers_id = c.prgm_sers_id
WHERE a.proj_id IN (1209624, 1209623, 1209625, 1211122, 1211123)
AND c.prgm_state_id IN (6, 7)
GROUP BY a.proj_title_ds, b.prgm_sers_title_nm
;vr,
Sudhakar B. -
Opposite functionality for Group By..?
Hi,
I have a source table as following:
PRODUCT
PID | QTY
P1 | 5
P2 | 1
P3 | 3
I want expected output as following:_
PID | QTY
P1 | 1
P1 | 1
P1 | 1
P1 | 1
P1 | 1
P2 | 1
P3 | 1
P3 | 1
P3 | 1
You can see in output table P1 should be repeated 5 times, P2 1 time and P3 3 times because of their respective values from QTY column in source table.
I have tried using WITH RECURSIVE clause but it is not working for me (Getting some syntax error).
Can anyone please help me out to solve the problem and get the desired result?
Edited by: 976056 on Dec 10, 2012 10:53 AMHi,
976056 wrote:
Hi Frank,
Thanks for the reply.
I have used following query but it is giving syntax error without any specific mention of which line might be incorrect.How do you know that it's a syntax error? Always post the complete error message.
What front end are you using? It probably has an option for dispalying decent error messages, including line numbers. If not, switch to some from end that does give you usable error messages.
WITH RECURSIVE queryy (PID, qty ) ASReveiw the syntax in the SQL Language manual.
The compiler will figure out that this is a recursive WITH clause; you don't have to use the keyword RECURSIVE. (In fact, you're not allowed to.)
SELECT A.PID, A.qty
FROM product A
UNION ALL
SELECT B.PID, Q.qty - 1 AS qty
FROM queryy Q , product B
WHERE Q.PID=B.PID
AND qty > 0Both q and b have a column called qty, so you need the qualify qty with the table alias. (Even if qty occurred in only 1 table, it would still be a tgood idea to say which table that was. Always qualify all columns in a multi-table query.)
If you make those 2 changes, then your query will run (assuming you have Oracle 11.2, of course. This shows one reason why you should always say which version of Oracle you're using.)
Do you really need to join the tables here? What is b supplying that is not already in q?
Say product.qty = 1. The 1st branch of the UNION will include that row, and the 2nd branch will also include the same pid, but with qty = 1 - 1= 0. I think you want to 2nd branch of the UNION to fail immediately if the original qty is not greater than 1 (as opposed to not greater than 0).
SELECT PID, 1 from queryy
ORDER BY 1;If you make all those changes, and format your query to make it readable, then you'll have something like:
WITH -- You don't have to say it's RECURSIVE
queryy (PID, qty ) AS
SELECT A.PID
, A.qty
FROM product A
UNION ALL
SELECT Q.PID
, Q.qty - 1 AS qty
FROM queryy Q
-- , product B -- B isn't contributing anything
WHERE -- Q.PID= B.PID -- ... so this comparison
-- AND -- ... is not needed
q.qty -- qty exists in both tables, so it must be qualified
> 1 -- not 0
SELECT PID
, 1
from queryy
ORDER BY 1
;which is basically what I posted earlier. -
Hi,
I have a problem using analytic function: when I execute this query
SELECT TSIUPSITE, TSIUPCEAN , TSIUPDATE, sum(TSIUPCA) TSIUPCA, TSIUPCTVA,TSIUPP4N,TSIUPPIEC,
sum(TSIUPQTE) TSIUPQTE,sum(TSIUPQTEP) TSIUPQTEP, TSIUPMDIU,TSIUPMDar,
sum(TSIUPCRIU) TSIUPCRIU,sum(TSIUPCRAR) TSIUPCRAR, trunc(TSIUPDCRE) TSIUPDCRE ,trunc(TSIUPDMAJ) TSIUPDMAJ ,
TSIUPUTIL,TSIUPTRT,TSIUPNERR,TSIUPMESS,
TSIUPTMVT,TSIUPSMAN, TSIUPMOTIF, sum(TSIUPMHT) TSIUPMHT, 0 vtanfisc,
TSIUPDATEVERIF,TSIUPNSEQ,TSIUPCINV ,count(*) over (partition by TSIUPSITE,TSIUPCEAN,TSIUP_TRT ) CONTA_ARTICOLO
FROM TST_FLIISR_VTEREMART
WHERE 1=1 --TSIUP_TRT = 1
AND TSIUPDATE=to_date('27082012','ddmmyyyy')
and TSIUP_NTRX =172
AND TSIUPSITE = 10025
AND TSIUPCEAN = '8012452018825'
GROUP BY TSIUPSITE, TSIUPCEAN , TSIUPDATE, TSIUPCTVA,TSIUPP4N,TSIUPPIEC,
TSIUPMDIU,TSIUPMDar, trunc(TSIUPDCRE),trunc(TSIUPDMAJ),TSIUPUTIL,TSIUPTRT,TSIUPNERR,TSIUPMESS,
TSIUPTMVT,TSIUPSMAN, TSIUPMOTIF, 0,
TSIUPDATEVERIF,TSIUPNSEQ,TSIUPCINV
ORDER BY TSIUPSITE,TSIUPDATE ;
I have the error ORA-00979: not a GROUP BY expression related to TSIUP_TRT field,infact, if I execute this one
SELECT TSIUPSITE, TSIUPCEAN , TSIUPDATE, sum(TSIUPCA) TSIUPCA, TSIUPCTVA,TSIUPP4N,TSIUPPIEC,
sum(TSIUPQTE) TSIUPQTE,sum(TSIUPQTEP) TSIUPQTEP, TSIUPMDIU,TSIUPMDar,
sum(TSIUPCRIU) TSIUPCRIU,sum(TSIUPCRAR) TSIUPCRAR, trunc(TSIUPDCRE) TSIUPDCRE ,trunc(TSIUPDMAJ) TSIUPDMAJ ,
TSIUPUTIL,TSIUPTRT,TSIUPNERR,TSIUPMESS,
TSIUPTMVT,TSIUPSMAN, TSIUPMOTIF, sum(TSIUPMHT) TSIUPMHT, 0 vtanfisc,
TSIUPDATEVERIF,TSIUPNSEQ,TSIUPCINV ,count(*) over (partition by TSIUPSITE,TSIUPCEAN ) CONTA_ARTICOLO
FROM TST_FLIISR_VTEREMART
WHERE 1=1 --TSIUP_TRT = 1
AND TSIUPDATE=to_date('27082012','ddmmyyyy')
and TSIUP_NTRX =172
AND TSIUPSITE = 10025
AND TSIUPCEAN = '8012452018825'
GROUP BY TSIUPSITE, TSIUPCEAN , TSIUPDATE, TSIUPCTVA,TSIUPP4N,TSIUPPIEC,
TSIUPMDIU,TSIUPMDar, trunc(TSIUPDCRE),trunc(TSIUPDMAJ),TSIUPUTIL,TSIUPTRT,TSIUPNERR,TSIUPMESS,
TSIUPTMVT,TSIUPSMAN, TSIUPMOTIF, 0,
TSIUPDATEVERIF,TSIUPNSEQ,TSIUPCINV
ORDER BY TSIUPSITE,TSIUPDATE ;
I have no problem. Now the difference between TSIUPCEAN ( or TSIUPSITE) and TSIUP_TRT is that TSIUP_TRT is not in Group By clause, but, to be honest, I don't know why I have this problem using using an analitic function.
Thanks for helpHi,
I think you are not using analytic function properly.
Analytical functions will execute for each row. Where as Group BY will execute for groups of data.
See below example for you reference.
Example 1:
-- Below query displays number of employees for each department. Since we have used analytical function for each row you are getting the number of employees based on the department id.
SQL> SELECT e.department_id,count(*) OVER (PARTITION BY e.department_id) cnt_analytic
2 FROM employees e
3 WHERE e.department_id IN (10,20,30);
DEPARTMENT_ID CNT_ANALYTIC
10 1
20 2
20 2
30 6
30 6
30 6
30 6
30 6
30 6
9 rows selected.
Example 2:
-- Since I have used GROUP BY clause I'm getting only single row for each department.
SQL> SELECT e.department_id, count(*) cnt_group
2 FROM employees e
3 WHERE e.department_id IN (10,20,30)
4 GROUP BY e.department_id;
DEPARTMENT_ID CNT_GROUP
10 1
20 2
30 6Finally, what I'm trying to explain you is - If you use Analytical function with GROUP BY clause, the query will not give the menaing ful result set.
See below
SQL> SELECT e.department_id,count(*) OVER (PARTITION BY e.department_id) cnt_analytic, count(*) cnt_grp
2 FROM employees e
3 WHERE e.department_id IN (10,20,30)
4 GROUP BY e.department_id;
DEPARTMENT_ID CNT_ANALYTIC CNT_GRP
10 1 1
20 1 2
30 1 6 -
How to use sum analytic function in adf
Hi
jdev 11.1.1.5
oracle 11g r2
I want to use analytic function (sum,count,avg and ...) .
I see [url http://andrejusb.blogspot.co.uk/2013/02/oracle-analytic-functions-for-total-and.html]Oracle Analytic Functions for Total and Average Calculation in ADF BC
and use it in my vo and jsf page,my vo have too much record and I want to have sum in table footer on demand (because of performance) and if user do not want to see the sum in footer of table it do not calculate sum,
what is your idea?Before I read that blog I use another vo for sum but after that blog decide to use analytic fuction becuase we have some page that have to many dvt graph and table and know we use seperate vo for them and it has not good performance and too many query must run in database ,I want to have 1 vo with some analytic function for graph and tables
-
Using analytic function in a view
Hello to all
Sorry If I use this thread
sql not merge using analytic functions
for my question,
From example you write and from Tom explain is not possible create a view on analytic function?
Thanks and sorry againI think what you'll discover is that if you apply the function over the result set, the initial SQL might be quicker,
for example, this is a test I did with a large dictionary view:
select tp.Table_Name
,tp.Partition_Name
from
select tbl.Table_Name as Table_Name
,tbl.Partition_Date as dt
,row_number() over (partition by dtp.table_Name order by dtp.Partition_Name desc) rn
from (
select /*+ all_rows */
dtp.Table_Name
,dtp.Partition_name
from dba_tab_partitions dtp
where dtp.Partition_Name like 'Y____\_Q_\_M__\_D__' escape '\'
and dtp.Table_Owner = 'APPS'
and dtp.Table_name not like '%$%'
and dtp.Table_Name like '%'
) tbl
) tp
where tp.rn = 1
select Table_Name
,Partition_Name
from (
select /*+ all_rows */
dtp.Table_Name
,row_number() over (partition by tbl.table_Name order by tbl.Partition_Name desc) rn
from dba_tab_partitions dtp
where dtp.Partition_Name like 'Y____\_Q_\_M__\_D__' escape '\'
and dtp.Table_Owner = 'APPS'
and dtp.Table_name not like '%$%'
and dtp.Table_Name '%'
) tbl
where rn = 1I found the former to be quicker.
I think ask tom was saying a lot more, but included something similar,
Edited by: bluefrog on Jun 10, 2010 12:48 PM -
How to use aggregate functions into Analytical functions
Can we use aggregate functions into analytical functions?
Please provide one example.
Smiles.HI Learner6
for information:
Aggregate Functions
Analytic Functions
for practic:
ORACLE-BASE - Analytic Functions
Thank you -
Hi all,
I want an help in creating my SQL query to extract the data described below:
I have one table example test containing data like below:
ID Desc Status
1 T1 DEACTIVE
2 T2 ACTIVE
3 T3 SUCCESS
4 T4 DEACTIVE
The thing i want to do is selecting all lines with ACTIVE status in this table but is there is no ACTIVE status, my query will give me the last line with DEACTIVE status.
Can I do this in one query by using analytical function for example, if yes can yiu help me on thaht query.
regards,
RaluceHi, Raluce,
Here's one way to do that:
WITH got_r_num AS
SELECT deptno, ename, job, hiredate
, ROW_NUMBER () OVER ( PARTITION BY deptno
ORDER BY job
, hiredate DESC
) AS r_num
FROM scott.emp
WHERE job IN ('ANALYST', 'CLERK')
SELECT deptno, ename, job, hiredate
FROM got_r_num
WHERE job = 'ANALYST'
OR r_num = 1
ORDER BY deptno
Since I don't have a sample version of your table, I used scott.emp to illustrate.
Output:
DEPTNO ENAME JOB HIREDATE
10 MILLER CLERK 23-JAN-82
20 SCOTT ANALYST 19-APR-87
20 FORD ANALYST 03-DEC-81
30 JAMES CLERK 03-DEC-81
This query finds all ANALYSTs in each department, regardless of how many there are. (Deptno 20 happens to have 2 ANALYSTs.) If there is no ANALYST in a department, then the most recently hired CLERK is included. (Deptnos 10 and 30 don't have any ANALYSTs.)
This "partitions", or sub-divides, the table into separate units, one for each department. In the problem you posted, it looks like you want to operate in the entire table, without sub-dividing it in any way. To do that, just omit the PARTITION BY clause in the analytic ROW_NUMBER function, like this:
WITH got_r_num AS
SELECT deptno, ename, job, hiredate
, ROW_NUMBER () OVER ( -- PARTITION BY deptno
ORDER BY job
, hiredate DESC
) AS r_num
FROM scott.emp
WHERE job IN ('ANALYST', 'CLERK')
SELECT deptno, ename, job, hiredate
FROM got_r_num
WHERE job = 'ANALYST'
OR r_num = 1
ORDER BY deptno -
2.1 EA Bug: group by auto complete generates group by for analytic function
Hi,
when using an analytic function in the sql text, sqldeveloper generates an automatic group by statement in the sql text.
Regards,
IngoPersonally, I don't want anything changed automatically EVER. The day you don't notice and you run a wrong statement, the consequences may be very costly (read: disaster).
Can this be turned off all together? If there's a preference I didn't find, can this be left off by default?
Thanks,
K. -
Grouping error in Oracle's analytic function PERCENTILE_CONT()
Hi,
I have a question regarding the usage of Oracle's analytic function PERCENTILE_CONT(). The underlying time data in the table is of hourly granularity and I want to fetch average, peak values for the day along with 80th percentile for that day. For the sake of clarification I am only posting relevant portion of the query.
Any idea how to rewrite the query and achieve the same objective?
SELECT TRUNC (sdd.ts) AS ts,
max(sdd.maxvalue) AS max_value, avg(sdd.avgvalue) AS avg_value,
PERCENTILE_CONT(0.80) WITHIN GROUP (ORDER BY sdd.avgvalue ASC) OVER (PARTITION BY pm.sysid,trunc(sdd.ts)) as Percentile_Cont_AVG
FROM XYZ
WHERE
XYZ
GROUP BY TRUNC (sdd.ts)
ORDER BY TRUNC (sdd.ts)
Oracle Error:
ERROR at line 5:
ORA-00979: not a GROUP BY expressionYou probably mixed up the aggregate and analytical versin of PERCENTILE_CONT.
The below should work, but i dont know if it produces the desireed results.
SELECT TRUNC (sdd.ts) AS ts,
max(sdd.maxvalue) AS max_value, avg(sdd.avgvalue) AS avg_value,
PERCENTILE_CONT(0.80) WITHIN GROUP (ORDER BY sdd.avgvalue ASC) as Percentile_Cont_AVG
FROM XYZ
sorry, what is this where clause for??
WHERE
XYZ
GROUP BY TRUNC (sdd.ts)
ORDER BY TRUNC (sdd.ts) Edited by: chris227 on 26.03.2013 05:45 -
GROUP BY and analytical functions
Hi all,
I need your help with grouping my data.
Below you can see sample of my data (in my case I have view where data is in almost same format).
with test_data as(
select '01' as code, 'SM' as abbreviation, 1010 as groupnum, 21 as pieces, 4.13 as volume, 3.186 as avgvolume from dual
union
select '01' as code, 'SM' as abbreviation, 2010 as groupnum, 21 as pieces, 0 as volume, 3.186 as avgvolume from dual
union
select '01' as code, 'SM' as abbreviation, 3000 as groupnum, 21 as pieces, 55 as volume, 3.186 as avgvolume from dual
union
select '01' as code, 'SM' as abbreviation, 3010 as groupnum, 21 as pieces, 7.77 as volume, 3.186 as avgvolume from dual
union
select '02' as code, 'SMP' as abbreviation, 1010 as groupnum, 30 as pieces, 2.99 as volume, 0.1 as avgvolume from dual
union
select '03' as code, 'SMC' as abbreviation, 1010 as groupnum, 10 as pieces, 4.59 as volume, 0.459 as avgvolume from dual
union
select '40' as code, 'DB' as abbreviation, 1010 as groupnum, 21 as pieces, 5.28 as avgvolume, 0.251 as avgvolume from dual
select
DECODE (GROUPING (code), 1, 'report total:', code) as code,
abbreviation as abbreviation,
groupnum as pricelistgrp,
sum(pieces) as pieces,
sum(volume) as volume,
sum(avgvolume) as avgvolume
--sum(sum(distinct pieces)) over (partition by code,groupnum) as piecessum,
--sum(volume) volume,
--round(sum(volume) / 82,3) as avgvolume
from test_data
group by grouping sets((code,abbreviation,groupnum,pieces,volume,avgvolume),null)
order by 1,3;Select statement which I have written returns the output below:
CODE ABBR GRPOUP PIECES VOLUME AVGVOL
01 SM 1010 21 4.13 3.186
01 SM 2010 21 0 3.186
01 SM 3000 21 55 3.186
01 SM 3010 21 7.77 3.186
02 SMP 1010 30 2.99 0.1
03 SMC 1010 10 4.59 0.459
40 DB 1010 21 5.28 0.251
report total: 145 79.76 13.554Number of pieces and avg volume is same for same codes (01 - pieces = 21, avgvolume = 3.186 etc.)
What I need is to get output like below:
CODE ABBR GRPOUP PIECES VOLUME AVGVOL
01 SM 1010 21 4.13 3.186
01 SM 2010 21 0 3.186
01 SM 3000 21 55 3.186
01 SM 3010 21 7.77 3.186
02 SMP 1010 30 2.99 0.1
03 SMC 1010 10 4.59 0.459
40 DB 1010 21 5.28 0.251
report total: 82 79.76 0.973Where total number of pieces is computed as sum of distinct numbers of pieces for each code -> *82 = 21 + 30 + 10 +21*.
Total volume is just sum of volumes in each row -> *79.76 = 4.13+0+55+7.77+2.99+4.59+5.28*.
And Average volume is computed as total volume / total number of pieces -> *0.973 = 79.76 / 82*.
I was trying to use analytical function (sum() over (partition by)) to get desired output, but without good results.
Could anyone help me with this issue?
Thanks in advance!
Regards,
JiriHi, Jiri,
Jiri N. wrote:
Hi all,
I need your help with grouping my data.
Below you can see sample of my data (in my case I have view where data is in almost same format).I assume the view guarantees that all rows with the same code (or the same code and groupnum) will always have the same pieces and the same avgvolume.
with test_data as( ...Thanks for posting this; it's very helpful.
What I need is to get output like below:
CODE ABBR GRPOUP PIECES VOLUME AVGVOL
01 SM 1010 21 4.13 3.186
01 SM 2010 21 0 3.186
01 SM 3000 21 55 3.186
01 SM 3010 21 7.77 3.186
02 SMP 1010 30 2.99 0.1
03 SMC 1010 10 4.59 0.459
40 DB 1010 21 5.28 0.251
report total: 82 79.76 0.973
Except for the last row, you're just displaying data straight from the table (or view).
It might be easier to get the results you want uisng a UNION. One branch of the UNION would get the"report total" row, and the other branch would get all the rest.
>
Where total number of pieces is computed as sum of distinct numbers of pieces for each code -> *82 = 21 + 30 + 10 +21*.It's not just distinct numbers. In this example, two different codes have pieces=21, so the total of distinct pieces is 61 = 21 + 30 + 10.
>
Total volume is just sum of volumes in each row -> *79.76 = 4.13+0+55+7.77+2.99+4.59+5.28*.
And Average volume is computed as total volume / total number of pieces -> *0.973 = 79.76 / 82*.
I was trying to use analytical function (sum() over (partition by)) to get desired output, but without good results. I would use nested aggregate functions to do that:
SELECT code
, abbreviation
, groupnum AS pricelistgrp
, pieces
, volume
, avgvolume
FROM test_data
UNION ALL
SELECT 'report total:' AS code
, NULL AS abbreviaion
, NULL AS pricelistgrp
, SUM (MAX (pieces)) AS pieces
, SUM (SUM (volume)) AS volume
, SUM (SUM (volume))
/ SUM (MAX (pieces)) AS avgvolume
FROM test_data
GROUP BY code -- , abbreviation?
ORDER BY code
, pricelistgrp
;Output:
CODE ABB PRICELISTGRP PIECES VOLUME AVGVOLUME
01 SM 1010 21 4.13 3.186
01 SM 2010 21 0.00 3.186
01 SM 3000 21 55.00 3.186
01 SM 3010 21 7.77 3.186
02 SMP 1010 30 2.99 .100
03 SMC 1010 10 4.59 .459
40 DB 1010 21 5.28 .251
report total: 82 79.76 .973It's unclear if you want to GROUP BY just code (like I did above) or by both code and abbreviation.
Given that this data is coming from a view, it might be simpler and/or more efficient to make separate version of the view, or to replicate most of the view in a query. -
I don't believe if analytic functions do it for me or not
Hey everyone,
I'm looking for a way handling this report for my own job.
a table having the following attributes exists.
Create table Test (
Public_Date varchar2(10),
City varchar2(10),
count number(3))
Query with the following output readily could be produced using group by clause.
Year Sum
2005 23
2006 36
2007 15
2008 10
But the question is that How I can lead to the following output.
(I want to merge some records into one record in the output, in this example
sum of all years after 2005 is my interest not each year individually come before)
Year(s) Sum
2005 23
2006 36
2007,2008 25 /*(15+10)*/
I think analytic functions may be useful in producing this output but I don't know how.
Could everyone help me how to handle this?Hi,
You can use a CASE (or DECODE) statement to map all the years after 2006 to some common value, like 9999, and GROUP BY that computed value.
If you want the 9999 row to be labeled '2007, 2008', do a search for "string aggregate" for various techniques, or see Tom Kyte's excellent page on this subject:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:2196162600402
I use STRAGG (near the top of the page).
Maybe you are looking for
-
Office Web Apps Farm Connection Issue SharePoint 2013
I have servers owa1 and owa2. Owa1 is acting as host and owa2 I joined to office web apps farm that's is to owa1. Both these are in office web apps farm and load balanced. Now my question is: From SharePoint Server when I connect , how should i conn
-
Error In enterprise Manager while deploying New RPD
Hi all, When i was deploying new RPD , BI publisher and Oracle RTD status shows down (under internal Applications) Can any one please help me out this problem. Thanks in Advance Satish
-
Using more than one ipod on a computer!
Hi, can anyone tell me how to use 3 different ipods on one computer, each having different playlists? I have to keep deleting and re-installing to update! Its driving me mad!If i plug in my ipod and my daughters songs are in the library, it wipes all
-
Using the Exceptions Table in a Mapping.
Hi,<BR><BR> For a specific mapping I want to catch errors (exceptions) caused by Constraint Violations. I Tried setting the Exceptions Table Name in the configuration of the mapping on the Target table but this doesnot seem to work. I guess I'm missi
-
Is there any way to tell iTunes to not display blank covers for songs with no album information? With over 2000 songs with no album information, I have to flip through 20-30 blank entries before I come across an actual full album in the coverflow fea