Analytic Function help
TABLE T1(R1_ID,R2,R3)
insert into t1 values(63,800,'1/1/2005')
insert into t1 values(64,841,'1/1/2005')
insert into t1 values(64,862,'1/1/2006')
insert into t1 values(64,879,'4/1/2007')
insert into t1 values(64,952,'4/1/2008')
insert into t1 values(64,980,'2/1/2009')
insert into t1 values(64,1010,'2/1/2010')
insert into t1 values(64,1041,'2/1/2011')
insert into t1 values(66,841,'1/1/2005')
insert into t1 values(66,862,'1/1/2006')
insert into t1 values(66,879,'4/1/2007')
insert into t1 values(66,952,'4/1/2008')
insert into t1 values(66,980,'2/1/2009')
insert into t1 values(66,1010,'2/1/2010')
insert into t1 values(66,1042,'2/1/2011')
insert into t1 values(67,841,'1/1/2005')
insert into t1 values(67,862,'1/1/2006')
insert into t1 values(67,879,'4/1/2007')
insert into t1 values(67,952,'4/1/2008')
insert into t1 values(67,980,'2/1/2009')
insert into t1 values(67,1009,'2/1/2010')
insert into t1 values(67,1035,'2/1/2011')
insert into t1 values(112,3660,'1/1/2005')
insert into t1 values(112,3806,'1/1/2006')
insert into t1 values(112,4500,'8/1/2006')
insert into t1 values(112,7280,'3/1/2007')
insert into t1 values(112,8600,'2/1/2008')
insert into t1 values(112,8818,'5/1/2008')
insert into t1 values(112,9170,'2/1/2009')
insert into t1 values(112,9489,'2/1/2010')
insert into t1 values(112,9778,'2/1/2011')
insert into t1 values(537,7000,'11/27/2005')
insert into t1 values(537,7000,'12/1/2005')
SELECT distinct R1_ID,MAX(R2) OVER(PARTITION BY R1_ID),MAX(R3) OVER(PARTITION BY R1_ID)
FROM T1
order by R1_ID
I WANT MAX OF R2 & R3 IN ONE SQL STATEMENT. IS THAT POSSIBLE?
ALTHOUGH I CAN WRITE A SUBQUERY WITH R3 TO GET THE RESULT.
with temp as(
SELECT R1_ID,R2,R3,
row_number() over(partition by R1_ID
order by R2 desc,R3 desc) rn
FROM T1)
select * from tmp where rn=1 order by R1_ID
Similar Messages
-
Does sql analytic function help to determine continuity in occurences
We need to solve this problem in a sql statement.
imagine a table test with two columns
create table test (id char(1), begin number, end number);
and these values
insert into test('a',1, 2);
insert into test('a',2,3);
insert into test('a',3,4);
insert into test('a',7,10);
insert into test('a',10,15);
insert into test('b',5,9);
insert into test('b',9,21);
insert into test('c',1,5);
our goal is to determine continuity in number sequence between begin and end attributes for a same id and determine min and max number from these contuinity chains.
The result may be
a, 1, 4
a, 7, 15
b, 5, 21
c, 1, 5
We test some analytic functions like lag, lead, row_number, min, max, partition by, etc to search a way to identify row set that represent a continuity but we didn't find a way to identify (mark) them so we can use min and max functions to extract extreme values.
Any idea is really welcome !Here is our implementation in a real context for example:
insert into requesterstage(requesterstage_i, requester_i, t_requesterstage_i, datefrom, dateto )
With ListToAdd as
(Select distinct support.requester_i,
support.datefrom,
support.dateto
from support
where support.datefrom < to_date('01.01.2006', 'dd.mm.yyyy')
and support.t_relief_i = t_relief_ipar.fgetflextypologyclassitem_i(t_relief_ipar.fismedicalexpenses)
and not exists
(select null
from requesterstage
where requesterstage.requester_i = support.requester_i
and support.datefrom < nvl(requesterstage.dateto, support.datefrom + 1)
and nvl(support.dateto, requesterstage.datefrom + 1) > requesterstage.datefrom)
ListToAddAnalyzed_1 as
(select requester_i,
datefrom,
dateto,
decode(datefrom,lag(dateto) over (partition by requester_i order by datefrom),0,1) data_set_start
from ListToAdd),
ListToAddAnalyzed_2 as
(select requester_i,
datefrom,
dateto,
data_set_start,
sum(data_set_start) over(order by requester_i, datefrom ) data_set_id
from ListToAddAnalyzed_1)
select requesterstage_iseq.nextval,
requester_i,
t_requesterstage_ipar.fgetflextypologyclassitem_i(t_requesterstage_ipar.fisbefore2006),
datefrom,
decode(sign(nvl(dateto, to_date('01.01.2006', 'dd.mm.yyyy')) -to_date('01.01.2006', 'dd.mm.yyyy')), 0, to_date('01.01.2006', 'dd.mm.yyyy'), -1, dateto, 1, to_date('01.01.2006', 'dd.mm.yyyy'))
from ( select requester_i
, min(datefrom) datefrom
, max(dateto) dateto
From ListToAddAnalyzed_2
group by requester_i, data_set_id
); -
Moving sum using date intervals - analytic functions help
let's say you have the following set of data:
DATE SALES
09/02/2012 100
09/02/2012 50
09/02/2012 10
09/02/2012 1000
09/02/2012 20
12/02/2012 1000
12/02/2012 1100
14/02/2012 1000
14/02/2012 100
15/02/2012 112500
15/02/2012 13500
15/02/2012 45000
15/02/2012 1500
19/02/2012 1500
20/02/2012 400
23/02/2012 2000
27/02/2012 4320
27/02/2012 300000
01/03/2012 100
04/03/2012 17280
06/03/2012 100
06/03/2012 100
06/03/2012 4320
08/03/2012 100
13/03/2012 1000
for each day i need to know the sum of the sales in the present and preceding 5 days (calendar) [not five rows].
What qurey could i use???
Please help!Hi.
Here's one way.
WITH data AS
SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d, 100 n FROM DUAL UNION ALL
SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d, 50 n FROM DUAL UNION ALL
SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d, 10 n FROM DUAL UNION ALL
SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d, 1000 n FROM DUAL UNION ALL
SELECT TO_DATE('09/02/2012','DD/MM/YYYY') d, 20 n FROM DUAL UNION ALL
SELECT TO_DATE('12/02/2012','DD/MM/YYYY') d, 1000 n FROM DUAL UNION ALL
SELECT TO_DATE('12/02/2012','DD/MM/YYYY') d, 1100 n FROM DUAL UNION ALL
SELECT TO_DATE('14/02/2012','DD/MM/YYYY') d, 1000 n FROM DUAL UNION ALL
SELECT TO_DATE('14/02/2012','DD/MM/YYYY') d, 100 n FROM DUAL UNION ALL
SELECT TO_DATE('15/02/2012','DD/MM/YYYY') d, 112500 n FROM DUAL UNION ALL
SELECT TO_DATE('15/02/2012','DD/MM/YYYY') d, 13500 n FROM DUAL UNION ALL
SELECT TO_DATE('15/02/2012','DD/MM/YYYY') d, 45000 n FROM DUAL UNION ALL
SELECT TO_DATE('15/02/2012','DD/MM/YYYY') d, 1500 n FROM DUAL UNION ALL
SELECT TO_DATE('19/02/2012','DD/MM/YYYY') d, 1500 n FROM DUAL UNION ALL
SELECT TO_DATE('20/02/2012','DD/MM/YYYY') d, 400 n FROM DUAL UNION ALL
SELECT TO_DATE('23/02/2012','DD/MM/YYYY') d, 2000 n FROM DUAL UNION ALL
SELECT TO_DATE('27/02/2012','DD/MM/YYYY') d, 4320 n FROM DUAL UNION ALL
SELECT TO_DATE('27/02/2012','DD/MM/YYYY') d, 300000 n FROM DUAL UNION ALL
SELECT TO_DATE('01/03/2012','DD/MM/YYYY') d, 100 n FROM DUAL UNION ALL
SELECT TO_DATE('04/03/2012','DD/MM/YYYY') d, 17280 n FROM DUAL UNION ALL
SELECT TO_DATE('06/03/2012','DD/MM/YYYY') d, 100 n FROM DUAL UNION ALL
SELECT TO_DATE('06/03/2012','DD/MM/YYYY') d, 100 n FROM DUAL UNION ALL
SELECT TO_DATE('06/03/2012','DD/MM/YYYY') d, 4320 n FROM DUAL UNION ALL
SELECT TO_DATE('08/03/2012','DD/MM/YYYY') d, 100 n FROM DUAL UNION ALL
SELECT TO_DATE('13/03/2012','DD/MM/YYYY') d, 1000 n FROM DUAL
days AS
SELECT TO_DATE('2012-02-01','YYYY-MM-DD')+(LEVEL-1) d
FROM DUAL
CONNECT BY LEVEL <= 60
totals_per_day AS
SELECT dy.d,SUM(NVL(dt.n,0)) total_day
FROM
data dt,
days dy
WHERE
dy.d = dt.d(+)
GROUP BY dy.d
ORDER BY 1
SELECT
d,
SUM(total_day) OVER
ORDER BY d
RANGE BETWEEN 5 PRECEDING AND CURRENT ROW
) AS five_day_total
FROM totals_per_day;
2012-02-01 00:00:00 0
2012-02-02 00:00:00 0
2012-02-03 00:00:00 0
2012-02-04 00:00:00 0
2012-02-05 00:00:00 0
2012-02-06 00:00:00 0
2012-02-07 00:00:00 0
2012-02-08 00:00:00 0
2012-02-09 00:00:00 1180
2012-02-10 00:00:00 1180
2012-02-11 00:00:00 1180
2012-02-12 00:00:00 3280
2012-02-13 00:00:00 3280
2012-02-14 00:00:00 4380
2012-02-15 00:00:00 175700
2012-02-16 00:00:00 175700
2012-02-17 00:00:00 175700
2012-02-18 00:00:00 173600
2012-02-19 00:00:00 175100
2012-02-20 00:00:00 174400
2012-02-21 00:00:00 1900
2012-02-22 00:00:00 1900
2012-02-23 00:00:00 3900
2012-02-24 00:00:00 3900
2012-02-25 00:00:00 2400
2012-02-26 00:00:00 2000
2012-02-27 00:00:00 306320
2012-02-28 00:00:00 306320
2012-02-29 00:00:00 304320
2012-03-01 00:00:00 304420
2012-03-02 00:00:00 304420
2012-03-03 00:00:00 304420
2012-03-04 00:00:00 17380
2012-03-05 00:00:00 17380
2012-03-06 00:00:00 21900
2012-03-07 00:00:00 21800
2012-03-08 00:00:00 21900
2012-03-09 00:00:00 21900
2012-03-10 00:00:00 4620
2012-03-11 00:00:00 4620
2012-03-12 00:00:00 100
2012-03-13 00:00:00 1100
2012-03-14 00:00:00 1000
2012-03-15 00:00:00 1000
2012-03-16 00:00:00 1000
2012-03-17 00:00:00 1000
2012-03-18 00:00:00 1000
2012-03-19 00:00:00 0
2012-03-20 00:00:00 0
2012-03-21 00:00:00 0
2012-03-22 00:00:00 0
2012-03-23 00:00:00 0
2012-03-24 00:00:00 0
2012-03-25 00:00:00 0
2012-03-26 00:00:00 0
2012-03-27 00:00:00 0
2012-03-28 00:00:00 0
2012-03-29 00:00:00 0
2012-03-30 00:00:00 0
2012-03-31 00:00:00 0Hope this helps.
Regards. -
Analytical function help needed
hi i'm using oracle 10g.
CREATE TABLE test100(
hcim VARCHAR2(10 BYTE),
bcim VARCHAR2(10 BYTE),
num VARCHAR2(6 BYTE),
mindate varchar2(10 byte))
insert into test100 values ('03217979','03236915','76120F','10/1/2006')
insert into test100 values ('03217979','03236916','76121F','10/1/2006')
insert into test100 values ('03217979','03236917','76122F','10/1/2006')
insert into test100 values ('03217979','03236918','76123F',null)
insert into test100 values ('03217979','03236919','76124F','11/1/2009')
SELECT hcim
, bcim
, num
, mindate
, Max(TO_DATE(mindate,'MM/DD/YYYY')) OVER (PARTITION BY hcim) AS mindate1
FROM test100
;output:
03217979 03236915 76120F 10/1/2006 11/1/2009
03217979 03236916 76121F 10/1/2006 11/1/2009
03217979 03236919 76124F 11/1/2009 11/1/2009
03217979 03236918 76123F 11/1/2009
03217979 03236917 76122F 10/1/2006 11/1/2009how can i show null in mindate1 column since one of the date value in mindate has a null. Only if there is no nulls then i need to show max(mindate) in mindate1
Thanks in advanceHi,
Thanks for posting the CREATE TABLE and INSERT statements; that's very helpful.
Do you mean you want mindate1 to be NULL on every row for that hcim, because at least one row in that hcim had a NULL mindate? It would help if you posted the exact results you want. (I was typing this message before your message, clarifying this point, was posted.) It would also help to have a couple of different hcims in the sample data, at least one with a NULL mindate, and another where mindate is never NULL.
I think you want something like this:
SELECT hcim
, bcim
, num
, mindate
, FIRST_VALUE ( TO_DATE (mindate, 'MM/DD/YYYY')
) OVER ( PARTITION BY hcim
ORDER BY TO_DATE (mindate, 'MM/DD/YYYY') DESC NULLS FIRST
) AS mindate1
FROM test100
;Output:
HCIM BCIM NUM MINDATE MINDATE1
03217979 03236916 76121F 10/1/2006
03217979 03236915 76120F 10/1/2006
03217979 03236917 76122F 10/1/2006
03217979 03236919 76124F 11/1/2009
03217979 03236918 76123FStoring dates in a VARCHAR2 column is a really bad idea. Why not use a DATE column? Coding will be simpler, errors will be fewer, and execution will be faster.
Edited by: Frank Kulash on Nov 11, 2011 4:53 PM -
I successfully use the following analytical function to sum all net_movement of a position (key for a position: bp_id, prtfl_num, instrmnt_id, cost_prc_crncy) from first occurrence until current row:
SELECT SUM (net_movement) OVER (PARTITION BY bp_id, prtfl_num, instrmnt_id, cost_prc_crncy ORDER BY TRUNC (val_dt) RANGE BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING) holding,
what i need is another column to sum net_movement of a position but only for the current date, but all my approaches fail..
- add the date (val_dt) to the 'partition by' clause and therefore sum only values with same position and date
SELECT SUM (net_movement) OVER (PARTITION BY val_dt, bp_id, prtfl_num, instrmnt_id, cost_prc_crncy ORDER BY TRUNC (val_dt) RANGE BETWEEN UNBOUNDED PRECEDING AND 0 FOLLOWING) today_net_movement
- take the holding for the last date and subtract it from the current holding afterwards
SELECT SUM (net_movement) OVER (PARTITION BY bp_id, prtfl_num, instrmnt_id, cost_prc_crncy ORDER BY TRUNC (val_dt) RANGE BETWEEN UNBOUNDED PRECEDING AND -1 FOLLOWING) last_holding,
- using lag on the analytical function which calculates holding fails too
I also want to avoid creating a table which stores the last holding..
Does anyone sees where I make a mistake or knows an alternative to get this value?
It would help me much!
Thanks in advance!Thank you,
but I already tried that but it returns strange values which are not the correct ones for sure.
It is always the same value for each row, if its not 0, and a very high one (500500 for example), even if the sum of all net_movement of that date is 0 (and the statement for holding returns 0 too)
I also tried witch trunc(val_dt,'DDD') with the same result (without trunc it is the same issue)
please help if you can, thanks in advance! -
I need help with Analytic Function
Hi,
I have this little problem that I need help with.
My datafile has thousands of records that look like...
Client_Id Region Countries
[1] [1] [USA, Canada]
[1] [2] [Australia, France, Germany]
[1] [3] [China, India, Korea]
[1] [4] [Brazil, Mexico]
[8] [1] [USA, Canada]
[9] [1] [USA, Canada]
[9] [4] [Argentina, Brazil]
[13] [1] [USA, Canada]
[15] [1] [USA]
[15] [4] [Argentina, Brazil]
etc
My task is is to create a report with 2 columns - Client_Id and Countries, to look something like...
Client_Id Countries
[1] [USA, Canada, Australia, France, Germany, China, India, Korea, Brazil, Mexico]
[8] [USA, Canada]
[9] [USA, Canada, Argentina, Brazil]
[13] [USA, Canada]
[15] [USA, Argentina, Brazil]
etc.
How can I achieve this using Analytic Function(s)?
Thanks.
BDFHi,
That's called String Aggregation , and the following site shows many ways to do it:
http://www.oracle-base.com/articles/10g/StringAggregationTechniques.php
Which one should you use? That depends on which version of Oracle you're using, and your exact requirements.
For example, is order importatn? You said the results shoudl include:
CLIENT_ID COUNTRIES
1 USA, Canada, Australia, France, Germany, China, India, Korea, Brazil, Mexicobut would you be equally happy with
CLIENT_ID COUNTRIES
1 Australia, France, Germany, China, India, Korea, Brazil, Mexico, USA, Canadaor
CLIENT_ID COUNTRIES
1 Australia, France, Germany, USA, Canada, Brazil, Mexico, China, India, Korea?
Mwalimu wrote:
... How can I achieve this using Analytic Function(s)?The best solution may not involve analytic functions at all. Is that okay?
If you'd like help, post your best attempt, a little sample data (CREATE TABLE and INSERT statements), the results you want from that data, and an explanation of how you get those results from that data.
Always say which version of Oracle you're using.
Edited by: Frank Kulash on Aug 29, 2011 3:05 PM -
About FIRST_ROW analytic function; can anyone help?
Hi everyone,
Can anyone help me with this simple query?
Let's suppose I have this query (the with clause contains some data):
WITH T AS (
SELECT 'TEST' as COL1, 1 as COL2, 'z' as COL3 FROM dual
UNION ALL
SELECT 'TEST', 2, 'y' FROM dual
UNION ALL
SELECT 'TEST', 2, 'h' FROM dual
SELECT FIRST_VALUE(COL1) OVER (PARTITION BY COL1), COL2, COL3
FROM T;I would like to have only the first row returned. I was thinking that with FIRST_VALUE it will be possible, but it returns 3 records.
So can anyone help me to have only the first record returned?
TEST 1 zThis is just a simple example. In reality I have thousands of records. I need to get only the first record based on the name (TEST in this example). We don't really care about the other columns.
Thanks for your help,user13117585 wrote:
I would like to have only the first row returned. I was thinking that with FIRST_VALUE it will be possible, but it returns 3 records. Analytic functions don't filter rows, they just calculate values from some part of the result set.
Aggregating is the most efficient way of doing this query:
SQL> WITH T AS (
2 SELECT 'TEST' as COL1, 1 as COL2, 'z' as COL3 FROM dual
3 UNION ALL
4 SELECT 'TEST', 2, 'y' FROM dual
5 UNION ALL
6 SELECT 'TEST', 2, 'h' FROM dual
7 )
8 select col1
9 , min(col2) col2
10 , max(col3) keep (dense_rank first order by col2) col3
11 from t
12 group by col1
13 /
COL1 COL2 C
TEST 1 z
1 row selected.Regards,
Rob. -
Help with Oracle Analytic Function scenario
Hi,
I am new to analytic functions and was wondering if someone could help me with the data scenario below. I have a table with the following data
COLUMN A COLUMN B COLUMN C
13368834 34323021 100
13368835 34438258 50
13368834 34438258 50
13368835 34323021 100
The output I want is
COLUMN A COLUMN B COLUMN C
13368834 34323021 100
13368835 34438258 50
A simple DISTINCT won't give me the desired output so i was wondering if there is any way that I can get the result using ANALYTIC FUNCTIONS and DISTINCT ..
Any help will be greatly appreciated.
Thanks.Hi,
Welcome to the forum!
Whenever you have a question, please post your sample data in a form that people can use to re-create the problem and test their solutions.
For example:
CREATE TABLE table_x
( columna NUMBER
, columnb NUMBER
, columnc NUMBER
INSERT INTO table_x (columna, columnb, columnc) VALUES (13368834, 34323021, 100);
INSERT INTO table_x (columna, columnb, columnc) VALUES (13368835, 34438258, 50);
INSERT INTO table_x (columna, columnb, columnc) VALUES (13368834, 34438258, 50);
INSERT INTO table_x (columna, columnb, columnc) VALUES (13368835, 34323021, 100);Do you want something that works in your version or Oracle? Of course you do! So tell us which version that is.
How do you get the results that you want? Explain what each row of output represents. It looks like
the 1st row contains the 1st distinct value from each column (where "first" means descending order for columnc, and ascending order for the others),
the 2nd row contains the 2nd distinct value,
the 3rd row contains the 3rd distinct value, and so on.
If that's what you want, here's one way to get it (in Oracle 9 and up):
WITH got_nums AS
SELECT columna, columnb, columnc
, DENSE_RANK () OVER (ORDER BY columna ) AS a_num
, DENSE_RANK () OVER (ORDER BY columnb ) AS b_num
, DENSE_RANK () OVER (ORDER BY columnc DESC) AS c_num
FROM table_x
SELECT MAX (a.columna) AS columna
, MAX (b.columnb) AS columnb
, MAX (c.columnc) AS columnc
FROM got_nums a
FULL OUTER JOIN got_nums b ON b.b_num = a.a_num
FULL OUTER JOIN got_nums c ON c.c_num = COALESCE (a.a_num, b.b_num)
GROUP BY COALESCE (a.a_num, b.b_num, c.c_num)
ORDER BY COALESCE (a.a_num, b.b_num, c.c_num)
;I've been trying to find a good name for this type of query. The best I've heard so far is "Prix Fixe Query", named after the menus where you get a choice of soups (listed in one column), appetizers (in another column), main dishes (in a 3rd column), and so on. The items on the first row don't necessaily have any relationship to each other.
The solution does not assume that there are the same number of distinct items in each column.
For example, if you add this row to the sample data:
INSERT INTO table_x (columna, columnb, columnc) VALUES (13368835, 34323021, 99);which is a copy of the last row, except that there is a completely new value for columnc, then the output is:
` COLUMNA COLUMNB COLUMNC
13368834 34323021 100
13368835 34438258 99
50starting in Oracle 11, you can also do this with an unpivot-pivot query. -
How to achive this using analytical function-- please help
version 10g.
this code works just fine with my requirement. i am tyring to learn analytical functions and implement that in the below query. i tried using row_number ,
but i could nt achive the desired results. please give me some ideas.
SELECT c.tax_idntfctn_nmbr irs_number, c.legal_name irs_name,
f.prvdr_lctn_iid
FROM tax_entity_detail c,
provider_detail e,
provider_location f,
provider_location_detail pld
WHERE c.tax_entity_sid = e.tax_entity_sid
AND e.prvdr_sid = f.prvdr_sid
AND pld.prvdr_lctn_iid = f.prvdr_lctn_iid
AND c.oprtnl_flag = 'A'
AND c.status_cid = 2
AND e.oprtnl_flag = 'A'
AND e.status_cid = 2
AND (c.from_date) =
(SELECT MAX (c1.from_date)
FROM tax_entity_detail c1
WHERE c1.tax_entity_sid = c.tax_entity_sid
AND c1.oprtnl_flag = 'A'
AND c1.status_cid = 2)
AND (e.from_date) =
(SELECT MAX (c1.from_date)
FROM provider_detail c1
WHERE c1.prvdr_sid = e.prvdr_sid
AND c1.oprtnl_flag = 'A'
AND c1.status_cid = 2)
AND pld.oprtnl_flag = 'A'
AND pld.status_cid = 2
AND (pld.from_date) =
(SELECT MAX (a1.from_date)
FROM provider_location_detail a1
WHERE a1.prvdr_lctn_iid = pld.prvdr_lctn_iid
AND a1.oprtnl_flag = 'A'
AND a1.status_cid = 2)thanks
Edited by: new learner on May 24, 2010 7:53 AM
Edited by: new learner on May 24, 2010 10:50 AMMay be like this not tested...
select *
from
SELECT c.tax_idntfctn_nmbr irs_number, c.legal_name irs_name,
f.prvdr_lctn_iid, c.from_date as c_from_date, max(c.from_date) over(partition by c.tax_entity_sid) as max_c_from_date,
e.from_date as e_from_date, max(e.from_date) over(partition by e.prvdr_sid) as max_e_from_date,
pld.from_date as pld_from_date, max(pld.from_date) over(partition by pld.prvdr_lctn_iid) as max_pld_from_date
FROM tax_entity_detail c,
provider_detail e,
provider_location f,
provider_location_detail pld
WHERE c.tax_entity_sid = e.tax_entity_sid
AND e.prvdr_sid = f.prvdr_sid
AND pld.prvdr_lctn_iid = f.prvdr_lctn_iid
AND c.oprtnl_flag = 'A'
AND c.status_cid = 2
AND e.oprtnl_flag = 'A'
AND e.status_cid = 2
AND pld.oprtnl_flag = 'A'
AND pld.status_cid = 2
)X
where c_from_date=max_c_from_date AND e_from_date =max_e_from_date AND
pld_from_date=max_pld_from_date -
Help needed with analytical function
I want to get the employee details of the highest and 2nd highest salaried employee in a particular department. But also the department should have more than 1 employee.
I tried the query and it gave me proper results. But I'm wondering if there is some other alternative than using the subquery.
Here is the table and the result query :
with t as
select 1 emp_id,3 mgr_id,'Rajesh' emp_name,3999 salary,677 bonus,'HR' dpt_nme from dual union
select 2 ,3 ,'Gangz',4500,800,'Finance' from dual union
select 3 ,4 ,'Sid',8000,12000,'IT' from dual union
select 4 ,null,'Ram',5000,677,'HR' from dual union
select 5 ,4,'Shyam',6000,677,'IT' from dual union
select 6 ,4 ,'Ravi',9000,12000,'IT' from dual
select * from
(select emp_id, mgr_id, emp_name, dpt_nme, salary, row_number() over (partition by dpt_nme order by salary desc) rn from t where dpt_nme in
(select dpt_nme from t group by dpt_nme having count(*) > 1)) where rn < 3Hi,
You need a sub-query, but you don't need more than that.
Here's one way to eliminate the extra sub-query:
WITH got_analytics AS
SELECT emp_id, mgr_id, emp_name, dpt_nme, salary
, ROW_NUMBER () OVER ( PARTITION BY dpt_nme
ORDER BY salary DESC
) AS rn
, COUNT (*) OVER ( PARTITION BY dpt_nme
) AS dpt_cnt
FROM t
SELECT emp_id, mgr_id, emp_name, dpt_nme, salary
, rn
FROM got_analytics
WHERE rn < 3
AND dpt_cnt > 1
;Analytic functions are computed after the WHERE clause is applied. Since we need to use the results of the analytic ROW_NUMBER function in a WHERE clause, that means we'll have to compute ROW_NUMBER in a sub-query, and use the results in the WHERE clause of the main query. We can call the analytic COUNT function in the same sub-query, and use its results in the same WHERE clause of the main query.
What results would you want if there's a tie for the 2nd highest salary in some department? For example, if you add this row to your sample data:
select 7 ,3 ,'Sunil',8000,12000,'IT' from dual union? You may want to use RANK instead of ROW_NUMBER. -
Table with 2 columns pro_id,sub_ver_id. Need only 5 pro_id for each sub_ver_id
SQL> select * from test1 order by SUB_VER_ID;
PRO_ID SUB_VER_ID
1 0
2 0
3 0
4 0
5 0
6 0
10 1
15 1
16 1
11 1
12 1
PRO_ID SUB_VER_ID
13 1
14 1
11 2
12 3
I'm new to analytic function i got query as below, but not able to get an idea to limit the SRLNO to only 5 rows for each SUB_VER_ID. Any hint would be much appreciated.
select distinct sub_ver_id,pro_id, row_number () over (order by sub_ver_id) srlno
from test1 order by sub_ver_idMay be as below..
select *
from
select sub_ver_id,pro_id, row_number () over (partition by sub_ver_id order by null) srlno
from test1
) where srlno <=5 order by sub_ver_idThanks... -
Help on Using Analytical Functions
I am hetting error when i use Analytical functions in Expressions
AVG( INGRP1.Test1 ) OVER (PARTITION BY INGRP1.Test2)
Error is as follows
Line 1, Col 28:
PLS-00103: Encountered the symbol "OVER" when expecting one of the following:
* & = - + ; < / > at in is mod remainder not rem
<an exponent (**)> <> or != or ~= >= <= <> and or like LIKE2_
LIKE4_ LIKEC_ between || multiset member SUBMULTISET_Hi,
the syntax of this part of the sql statement is okay. Please post the complete statement to identify the error.
Sometimes oracle identifies the wrong point for the error.
Regards,
Detlef -
Help with analytical function (ora 9...)
Hi everyone, is there a way to fill some missing numbers based on what have come before and after that missing number by starttime and based on how many missing data are between? ... by "simple" select? I know how to do that just theoreticly with simple math commands, but is there a way to apply them in sql (analytical functions)?
Thanks in advance for any ideas !
The missing number on line 17 could be calculated as 339+(1/2)*(356-339) = 347,5
The missing number on line 23 could be calculated as 355+(1/3)*(292-355) = 334
The missing number on line 24 could be calculated as 355+(2/3)*(292-355) = 313
rownumber + temp_table (starttime,data_column)
15 23.5.2007 16:15 , 258
16 23.5.2007 16:30 , 339
17 23.5.2007 16:45 ,
18 23.5.2007 17:00 , 356
19 23.5.2007 17:15 , 373
20 23.5.2007 17:30 , 355
21 23.5.2007 17:45 , 363
22 23.5.2007 18:00 , 355
23 23.5.2007 18:15 ,
24 23.5.2007 18:30 ,
25 23.5.2007 19:00 , 292
26 23.5.2007 19:15 , 295
THANKS
Message was edited by:
dusooWay too late, but I wouldn't let my effort go unpublished ;-)
SQL> create table temp_table
2 as
3 select 15 rownumber, to_date('23.5.2007 16:15','dd.mm.yyyy hh24:mi') starttime, 258 data_column from dual union all
4 select 16, to_date(' 23.5.2007 16:30','dd.mm.yyyy hh24:mi'), 339 from dual union all
5 select 17, to_date(' 23.5.2007 16:45','dd.mm.yyyy hh24:mi'), null from dual union all
6 select 18, to_date(' 23.5.2007 17:00','dd.mm.yyyy hh24:mi'), 356 from dual union all
7 select 19, to_date(' 23.5.2007 17:15','dd.mm.yyyy hh24:mi'), 373 from dual union all
8 select 20, to_date(' 23.5.2007 17:30','dd.mm.yyyy hh24:mi'), 355 from dual union all
9 select 21, to_date(' 23.5.2007 17:45','dd.mm.yyyy hh24:mi'), 363 from dual union all
10 select 22, to_date(' 23.5.2007 18:00','dd.mm.yyyy hh24:mi'), 355 from dual union all
11 select 23, to_date(' 23.5.2007 18:15','dd.mm.yyyy hh24:mi'), null from dual union all
12 select 24, to_date(' 23.5.2007 18:30','dd.mm.yyyy hh24:mi'), null from dual union all
13 select 25, to_date(' 23.5.2007 19:00','dd.mm.yyyy hh24:mi'), 292 from dual union all
14 select 26, to_date(' 23.5.2007 19:15','dd.mm.yyyy hh24:mi'), 295 from dual
15 /
Tabel is aangemaakt.
SQL> with t as
2 ( select t.*
3 , max(case when data_column is not null then rownumber end) over (order by rownumber) lowerbound
4 , last_value(data_column ignore nulls) over (order by rownumber) prevvalue
5 , min(case when data_column is not null then rownumber end) over (order by rownumber desc) upperbound
6 , last_value(data_column ignore nulls) over (order by rownumber desc) nextvalue
7 from temp_table t
8 )
9 select rownumber
10 , starttime
11 , case
12 when data_column is not null then data_column
13 else prevvalue * ((upperbound - rownumber) / (upperbound - lowerbound))
14 + nextvalue * ((rownumber - lowerbound) / (upperbound - lowerbound))
15 end data_column
16 from t
17 order by rownumber
18 /
ROWNUMBER STARTTIME DATA_COLUMN
15 23-05-2007 16:15:00 258
16 23-05-2007 16:30:00 339
17 23-05-2007 16:45:00 347,5
18 23-05-2007 17:00:00 356
19 23-05-2007 17:15:00 373
20 23-05-2007 17:30:00 355
21 23-05-2007 17:45:00 363
22 23-05-2007 18:00:00 355
23 23-05-2007 18:15:00 334
24 23-05-2007 18:30:00 313
25 23-05-2007 19:00:00 292
26 23-05-2007 19:15:00 295
12 rijen zijn geselecteerd.Regards,
Rob. -
Analytical function syntax help
The following query sorts by most occuring hesid descedning and requires TWO full table scans of the episodes_full_test table :
create table episodes_full_test (epikey number, hesid number, dob date) tablespace analysis_ip_d;
insert into episodes_full_test values (100, 20, to_date('31-07-1975','DD-MM-YYYY'));
insert into episodes_full_test values (101, 20, to_date('31-07-1975','DD-MM-YYYY'));
insert into episodes_full_test values (102, 20, to_date('31-07-1975','DD-MM-YYYY'));
insert into episodes_full_test values (103, 20, to_date('31-07-1975','DD-MM-YYYY'));
insert into episodes_full_test values (104, 10, to_date('31-07-1985','DD-MM-YYYY'));
insert into episodes_full_test values (105, 30, to_date('31-07-1995','DD-MM-YYYY'));
insert into episodes_full_test values (106, 30, to_date('31-07-1995','DD-MM-YYYY'));
insert into episodes_full_test values (107, 30, to_date('31-07-1995','DD-MM-YYYY'));
commit;
select eft.hesid, eft.epikey, eft.dob
from episodes_full_test eft
join (select hesid, count(hesid) count_hesid
from episodes_full_test
group by hesid) v1
on eft.hesid = v1.hesid
order by v1.count_hesid desc, eft.epikey;
HESID EPIKEY DOB
20 100 31/07/1975
20 101 31/07/1975
20 102 31/07/1975
20 103 31/07/1975
30 105 31/07/1995
30 106 31/07/1995
30 107 31/07/1995
10 104 31/07/1985
I'm sure there's a way to use analytical functions such that Oracle only needs to perform ONE full table scan of episodes_full_test, but I can't figure out the syntax
Can anyone advise please ?
(Oracle 9r2)
Thanks, GusThank you for providing the create table, insert commands and required output as it makes answering the question much easier (once I'd removed the tablespace specification)
SQL> select hesid, epikey, dob
2 from
3 (
4 select eft.hesid, eft.epikey, eft.dob,
5 count(*) over (partition by eft.hesid) count_hesid
6 from episodes_full_test eft
7 )
8 order by count_hesid desc;
HESID EPIKEY DOB
20 100 31-JUL-75
20 101 31-JUL-75
20 102 31-JUL-75
20 103 31-JUL-75
30 105 31-JUL-95
30 106 31-JUL-95
30 107 31-JUL-95
10 104 31-JUL-85
8 rows selected.
SQL> -
Help me on Analytical function
Hi
I'm using oracle version as
SQL> select * From v$version;
BANNER
Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64bit Production
PL/SQL Release 9.2.0.8.0 - Production
CORE 9.2.0.8.0 Production
TNS for Solaris: Version 9.2.0.8.0 - Production
NLSRTL Version 9.2.0.8.0 - Productioni have a following tables
CREATE TABLE emp_info(emp_id number,ename varchar2(10),chk_date date);
CREATE TABLE emp_month(emp_id number,emp_month_date date,chk_amt number(10,2));
insert into emp_info VALUES (101,'PAUL',to_date('01-MAR-2009','DD-MON-YYYY'));
insert into emp_info VALUES (102,'JOHN',to_date('01-APR-2009','DD-MON-YYYY'));
insert into emp_info VALUES (103,'KRIS',to_date('01-MAY-2009','DD-MON-YYYY'));
insert into emp_month values (101,'01-DEC-2008',1432);
insert into emp_month values (101,'01-JAN-2009',1412);
insert into emp_month values (101,'01-FEB-2009',1632);
insert into emp_month values (101,'01-MAR-2009',1672);
insert into emp_month values (102,'01-DEC-2008',2678);
insert into emp_month values (102,'01-JAN-2009',2786);
insert into emp_month values (102,'01-FEB-2009',2883);
insert into emp_month values (102,'01-MAR-2009',2653);
insert into emp_month values (102,'01-APR-2009',2653);
insert into emp_month values (103,'01-NOV-2008',2343);
insert into emp_month values (103,'01-DEC-2008',2311);
insert into emp_month values (103,'01-JAN-2009',3122);
insert into emp_month values (103,'01-FEB-2009',3412);
insert into emp_month values (103,'01-MAR-2009',3312);
insert into emp_month values (103,'01-APR-2009',3315);
insert into emp_month values (103,'01-MAY-2009',4321);i'm using following QUERY, to get the results. Is it possible to get these same results using ANALYTICAL functions
or i would appreciate any better solution than this.
Select e.emp_id,e.ename,e.chk_date,sum(chk_amt) year_amt
from emp_month em
,(select emp_id,ename,chk_date
from emp_info)e
where e.emp_id = em.emp_id
and em.emp_month_date between trunc(e.chk_date,'YY') AND e.chk_date
group by e.emp_id,e.ename,e.chk_dateuser12212962 wrote:
i'm using following QUERY, to get the results. Is it possible to get these same results using ANALYTICAL functionsor i would appreciate any better solution than this.
I have no idea why you would need analytic function. What I do know: there is no need for inline view in your query:
SQL> Select e.emp_id,e.ename,e.chk_date,sum(chk_amt) year_amt
2 from emp_month em
3 ,(select emp_id,ename,chk_date
4 from emp_info)e
5 where e.emp_id = em.emp_id
6 and em.emp_month_date between trunc(e.chk_date,'YY') AND e.chk_date
7 group by e.emp_id,e.ename,e.chk_date
8
SQL> /
EMP_ID ENAME CHK_DATE YEAR_AMT
102 JOHN 01-APR-09 10975
101 PAUL 01-MAR-09 4716
103 KRIS 01-MAY-09 17482
SQL> Select e.emp_id,e.ename,e.chk_date,sum(chk_amt) year_amt
2 from emp_month em,
3 emp_info e
4 where e.emp_id = em.emp_id
5 and em.emp_month_date between trunc(e.chk_date,'YY') AND e.chk_date
6 group by e.emp_id,e.ename,e.chk_date
7 /
EMP_ID ENAME CHK_DATE YEAR_AMT
102 JOHN 01-APR-09 10975
101 PAUL 01-MAR-09 4716
103 KRIS 01-MAY-09 17482
SQL> SY.
Maybe you are looking for
-
What's a good USB 3.0 hub?
I've got a late 2012 Mac mini. Mavericks OS (10.9.4). I have lots of USB devices, most of them of the 2.0 variety, a couple 3.0. I bought an inexpensive "USB 3.0" hub, and it causes the Mac not to wake from sleep mode. Instead it just powers off, and
-
I have to "single-click" twice (not double click) to open an item in the Dock.
Can someone confirm if this is Expected Behavior?? (OS = Mavericks) If you have Assigned an application in your Dock to a Desktop & Display in the application's Dock >> Options (ex: Assigned To: Desktop on Display 2): Click once on the applicatio
-
How can I fade in/out audio only below a certain frequency?
I have an MP3 made from a MIDI file in which all instruments are unfortunately in a single track. I want to fade the tom part in because I thought it would be easy considering its obvious separation from the marimba part in the Spectral Pitch Display
-
Save as- for Dummies (Numbers version)
Here is a clean way to retrieve Save As… in Numbers. --(SCRIPT Numbers_save_a_copy] Enregistrer le script en tant que Script : Numbers_save_a_copy.scpt déplacer le fichier créé dans le dossier <VolumeDeDémarrage>:Utilisateurs:<votreCompte>:Bibliothèq
-
Macbook pro 13 inch glassreplacement
Granddaughter has a Macbook pro 13 in.the new unibody design, the glass is cracked can I get just the glass replaced as the computer still works?