Home » SQL & PL/SQL » SQL & PL/SQL » Oracle MAX (Oracle 10g)
Oracle MAX [message #539823] Wed, 18 January 2012 12:05 Go to next message
pronosen
Messages: 5
Registered: January 2012
Junior Member
Hello--

I am a new user to Oracle. The challenge I am currently facing is finding the maximum value of two independent columns of a single table.
Here is the structure of the table:
[FiscalYear] [AccountingPeriod]
------------ ------------------
[2012] ------------- [2]
[2011] ------------- [12]
[2012] ------------- [1]

What I need to be able to do is to:
1) Determine the maximum value present in column FiscalYear, and then the maximum value available for this FiscalYear under the column AccountingPeriod.

Having previous MS SQL experience, I can do this fairly easy on Microsoft SQL server, but so far was not able to do this easily on Oracle database. My other observation is that using the MAX function on Oracle is very slow (even with thse fields being indexed). So, my question is: Is it possible to run this query on Oracle with only one pass through the table where th returned result will show 2012 for FiscalYear, and 2 for Accounting Period?

Thank you in advance.

[Updated on: Wed, 18 January 2012 12:07]

Report message to a moderator

Re: Oracle MAX [message #539824 is a reply to message #539823] Wed, 18 January 2012 12:06 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
It would be helpful if you followed Posting Guidelines - http://www.orafaq.com/forum/t/88153/0/
Re: Oracle MAX [message #539827 is a reply to message #539824] Wed, 18 January 2012 12:16 Go to previous messageGo to next message
Michel Cadot
Messages: 68761
Registered: March 2007
Location: Saint-Maur, France, https...
Senior Member
Account Moderator
For all SQL or PL/SQL question, Post a working Test case: create table and insert statements along with the result you want with these data then we will be able work with your table and data. Explain with words and sentences the rules that lead to this result.

Before, Please read OraFAQ Forum Guide and How to use [code] tags and make your code easier to read.
Make sure that lines of code do not exceed 80 characters when you format.
Indent the code, use code tags and align the columns in result.
Use the "Preview Message" button to verify.
Also always post your Oracle version, with 4 decimals.

Quote:
Is it possible to run this query on Oracle with only one pass through the table where th returned result will show 2012 for FiscalYear, and 2 for Accounting Period?

Yes use MAX in its analytic form, see Analytic Functions.

Rgards
Michel
Re: Oracle MAX [message #539838 is a reply to message #539823] Wed, 18 January 2012 13:57 Go to previous messageGo to next message
pronosen
Messages: 5
Registered: January 2012
Junior Member
Per previous requests, here is my MS SQL code (I don't know if it will also work on Oracle)that creates table and some random data.

DECLARE @Table TABLE (FISCAL_YEAR INT, ACCOUNTING_PERIOD INT)
INSERT @Table VALUES(2012, 2)
INSERT @Table VALUES(2011, 12)
INSERT @Table VALUES(2012, 1)

Is it possible in Oracle to return data in one single pass through the table that would return only one line with maximum value for the FISCAL_YEAR column, and maximum value present under CCOUNTING_PERIOD column that is available for the MAX(FISCAL_YEAR) present. In this example the data returned should show 2012 for FISCAL_YEAR, and 2 for ACCOUNTING_PERIOD.

Is it also possible to do this by not using the MAX() function as it runs slow on Oracle?

Thank you.

[Updated on: Wed, 18 January 2012 13:59]

Report message to a moderator

Re: Oracle MAX [message #539839 is a reply to message #539838] Wed, 18 January 2012 14:15 Go to previous messageGo to next message
Solomon Yakobson
Messages: 3305
Registered: January 2010
Location: Connecticut, USA
Senior Member
pronosen wrote on Wed, 18 January 2012 14:57
Is it also possible to do this by not using the MAX() function as it runs slow on Oracle?


What is slow? So far I do not see any SQL you ran. Do you have one? If so post it along with explain plan and timing.

SY.
Re: Oracle MAX [message #539840 is a reply to message #539838] Wed, 18 January 2012 15:16 Go to previous messageGo to next message
John Watson
Messages: 8979
Registered: January 2010
Location: Global Village
Senior Member
There isn't much point in posting SQL Server code. This is what we need:
create table atable(fiscal_year integer,accounting_period integer);
insert into atable values(2012,2);
insert into atable values(2011,12);
insert into atable values(2012,1);

Is this what you want -
orcl> select fiscal_year,max(accounting_period) from
  2  (select * from atable where fiscal_year=(select max(fiscal_year) from atable))
  3  group by fiscal_year;

FISCAL_YEAR MAX(ACCOUNTING_PERIOD)
----------- ----------------------
       2012                      2
Re: Oracle MAX [message #539843 is a reply to message #539840] Wed, 18 January 2012 16:54 Go to previous messageGo to next message
pronosen
Messages: 5
Registered: January 2012
Junior Member
John, thank you for your help.
I tried running your code, and it indeed returns data I was looking for. The only problem is that it takes over 5 minutes for the query to complete. I don't have access to the database itself (other than read-only access to the view that generates the data), so I am not totally sure if ACCOUNTING_PERIOD field is indexed. Though FISCAL_YEAR field is indexed for sure.
I also know that the underlying table has more than 30 million records in it.

I found online some articles stating that performance of MAX() function on Oracle does not offer the fastest return of results. Instead, these articles kept advising the usage of the ROWNUM = 1 approach (in conjunction with ORDER BY clause).

I also wrote the query to return the same resultset that looks like this:

SELECT
MAX(FISCAL_YEAR) KEEP (DENSE_RANK FIRST ORDER BY FISCAL_YEAR DESC) FISCAL_YEAR,
MAX(ACCOUNTING_PERIOD) KEEP (DENSE_RANK FIRST ORDER BY FISCAL_YEAR DESC, ACCOUNTING_PERIOD DESC) ACCOUNTING_PERIOD
FROM atable

This query returns data in slightly over 2 minutes, which is still way too long.
I wonder if there isn't any other way to return the data needed that may work faster, and perhaps without the MAX() function?

Thank you.
Re: Oracle MAX [message #539845 is a reply to message #539843] Wed, 18 January 2012 18:48 Go to previous messageGo to next message
BlackSwan
Messages: 26766
Registered: January 2009
Location: SoCal
Senior Member
I wish I had data to test below against
WITH max_val
     AS (SELECT fiscal_year,
                accounting_period
         FROM   atable
         ORDER  BY 1,
                   2 DESC)
SELECT fiscal_year,
       accounting_period
FROM   max_val
WHERE  ROWNUM = 1;  
Re: Oracle MAX [message #539850 is a reply to message #539845] Wed, 18 January 2012 22:41 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9106
Registered: November 2002
Location: California, USA
Senior Member
You left out one DESC.

WITH max_val
     AS (SELECT fiscal_year,
                accounting_period
         FROM   atable
         ORDER  BY 1 DESC,
                   2 DESC)
SELECT fiscal_year,
       accounting_period
FROM   max_val
WHERE  ROWNUM = 1;  

Re: Oracle MAX [message #540003 is a reply to message #539850] Thu, 19 January 2012 12:14 Go to previous messageGo to next message
pronosen
Messages: 5
Registered: January 2012
Junior Member
BlackSwan & Barbara: thank you for your input.
I tried running the code you posted against the datasource:

WITH max_val
AS (SELECT fiscal_year,
accounting_period
FROM atable
ORDER BY 1 DESC,
2 DESC)
SELECT fiscal_year,
accounting_period
FROM max_val
WHERE ROWNUM = 1;

This code runs about 6 sec faster than the one I was using before (2m6s instead 2m12s):

SELECT
MAX(FISCAL_YEAR) KEEP (DENSE_RANK FIRST ORDER BY FISCAL_YEAR DESC) FISCAL_YEAR,
MAX(ACCOUNTING_PERIOD) KEEP (DENSE_RANK FIRST ORDER BY FISCAL_YEAR DESC, ACCOUNTING_PERIOD DESC) ACCOUNTING_PERIOD
FROM atable

I am starting to suspect that the ACCOUNTING_PERIOD field is not indexed, and that's why this query takes so long. Another indication of this point is that it takes 0sec to return MAX(FISCAL_YEAR) by itself, and very long to return MAX(ACCOUNTING_PERIOD) by itself.

One more question: In the code you posted, (the part "ORDER BY 1 DESC, 2 DESC"), do numbers 1 and 2 represent the column positions in the ACTUAL UNDERLYING TABLE, or column positions under the "WITH max_val" temp. table?

Once again, thank you all for your assistance.
Re: Oracle MAX [message #540009 is a reply to message #540003] Thu, 19 January 2012 12:51 Go to previous messageGo to next message
Barbara Boehmer
Messages: 9106
Registered: November 2002
Location: California, USA
Senior Member
pronosen wrote on Thu, 19 January 2012 10:14


I am starting to suspect that the ACCOUNTING_PERIOD field is not indexed, and that's why this query takes so long. Another indication of this point is that it takes 0sec to return MAX(FISCAL_YEAR) by itself, and very long to return MAX(ACCOUNTING_PERIOD) by itself.


You can select from user_indexes or all_indexes to see what indexes are on your table. You can also SET AUTOTRACE ON from SQL*Plus before running the query to see what execution plan the optimizer is using. You can also run DBMS_STATS.GATHER_TABLE_STATS(USER, 'ATABLE') to ensure that the statistics that the optimizer uses to select the execution plan are current.


pronosen wrote on Thu, 19 January 2012 10:14


One more question: In the code you posted, (the part "ORDER BY 1 DESC, 2 DESC"), do numbers 1 and 2 represent the column positions in the ACTUAL UNDERLYING TABLE, or column positions under the "WITH max_val" temp. table?


The 1 and 2 are the column positions in that sub-query, not the underlying table. In this case, that sub-query is the only sub-query in the sub-query factoring (with) clause, but it can have more than one such sub-query. It is not a temporary table.
Re: Oracle MAX [message #540019 is a reply to message #540009] Thu, 19 January 2012 13:44 Go to previous message
pronosen
Messages: 5
Registered: January 2012
Junior Member
Thanks, Barbara! Your answer was very helpful.
Previous Topic: Combinations
Next Topic: Update using data from another table
Goto Forum:
  


Current Time: Mon Jul 21 13:21:51 CDT 2025