Question

How can I write a query to group by the names of the partitions on a table?

Asked by: tf842

i.e.:
Instead of
Select purchase_date, sum(amt)
from mytable
group by purchase_date

do this:
select partition_name p_name, sum(amt) total
from mytable
group by partition_name

given mytable has 3 partitions named, p1, p2 and p3
the result should look like this:
p_name total
p1         1000.25
p2         1300.50
p3         2400.42

Thank you for your consideration.
Sami

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2005-09-22 at 09:09:06ID21570698
Topic

Oracle Database

Participating Experts
6
Points
500
Comments
17

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. table partition
    I can't understand the table partition in oracle 8. Explain me briefly the concept with an example
  2. Partitioning a Large Table
    I am trying to partition a large table (> 1 Billion rows). I have chosen to partition it by range and have mapped out a range pattern like this Create Table UC_Part Partition by Range (mx_num) ( partition p1 values less than (17348274) Tablespace TS_P1, Partition P2 val...
  3. Partitioning
    Hi friends, I have a doubt regarding Partitioning of tables. I have a table sales with columns Shopper_id, Product_id, Transaction_date, Sales_qty, Sales_amt. The above table contains 1 billion records. Range of values for each column: Shopper_id= 1 to 100000 Id's, produc...
  4. partition question
    I have the following row count on table emp. If the query always use dept_no, will the query be faster if I partition by dept_no? If so, How to partition ? Thanks. COUNT(*) DEPT_NO 1096773 12 651 999 95 82 1...
  5. What is P1:BEGIN and P2:BEGIN do?
    Can someone explain P1: & P2: to me? (or maybe point me at a BONEHEAD doc?) I found a StoredProc sample using a GLOBAL TEMPORARY TABLE and a CURSOR ... It uses P1: and P2: ..... My StoredProc (using P1: & P2:) compiles and creates the StoredProc in the library, but a...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: paquicubaPosted on 2005-09-22 at 09:29:14ID: 14938106

Can you provide more details...
* Table structure
* Sample data

First you use <purchase_date>, then <partition_name>  <<--- What are trying to group here

 

by: markgeerPosted on 2005-09-22 at 09:34:44ID: 14938153

That's a good question.  I'm not sure there is a way to do that easily in a single SQL statement.  (I'm posting this partly to get e-mail notification from other postings here, in case someone else knows of a way.)

One possibility would be to write a PL\SQL procedure that starts with a query from user_tab_partitions (or: all_tab_partitions) to get the partition names, then a second query from each partition in turn, but that would require the use of dynamic SQL (execute immediate).   Plus, getting the results from that back to a single select statement would be a challenge.

 

by: tf842Posted on 2005-09-22 at 09:36:53ID: 14938170


***>First you use <purchase_date>, then <partition_name>  <<--- What are trying to group here
Purchase_date is the column on which the partitions exist, with the potential for multiple dates per partition.
i.e.:
P1 might be 1/1/2000 - 12/31/2002
P2 might be 1/1/2003 - 12/31/2003
P3 might be 1/1/2004 - forward

We are trying to group by the logic used for the partitions without having to replicate the logic in the query.

Partitions are occassionally added and removed. We want to create a query that will group by the current partitions and return their respective partition name and total.

We do not want to loop through the partition names if possible. We know how to do that.

Sami

 

by: jrb1Posted on 2005-09-22 at 09:37:31ID: 14938175

How is the table partitioned?  By range?

 

by: tf842Posted on 2005-09-22 at 09:40:54ID: 14938212

It is partitioned by a range of calendar dates (in our case, purchase_date) as shown above.
Sami

 

by: ram_0218Posted on 2005-09-22 at 09:54:33ID: 14938330

if you know the columns and the way its partitioned, then i guess you can do this by joining user_tab_partitions with your table., Thats my perception, anyway!!

 

by: ram_0218Posted on 2005-09-22 at 09:58:37ID: 14938369

Try this,

select partition_name,partkey,(select sum(amt) from <yourtabname> where keyfield=partkey) --or the range you want to compare
from  (select partition_name,high_value partkey from user_tab_partitions where table_name=<yourtabname>);

 

by: slightwvPosted on 2005-09-22 at 09:59:10ID: 14938375

Bizarre question:  Why would you want to do this?

If I run this query today and get:
p1 100
p2 200
p3 300

and someone doubles the range of p1 and cuts the range of p2 by half.

Then I run the query again a day or so later, and get:
p1 400
p2 25
p3 350

What does that tell me?

 

by: markgeerPosted on 2005-09-22 at 10:03:21ID: 14938420

I think what makes this a challenge is the fact that Oracle implemented partitioning intentionally in a way that would not break existing applications at the time.  So, standard SQL statements in Oracle are not aware of the partitions.  The optimizer knows about them, and statements can be written that reference (or are limited to) a particular partition, but I don't know of a way to write one query that spans multiple partiions, yet pays attention to the partition boundaries.

 

by: jrb1Posted on 2005-09-22 at 10:06:01ID: 14938446

Here is a function that will return the partition a date value belongs to:

create or replace function GetPartitionNameRange (i_table_name varchar2, i_value varchar2) return varchar2
is
   v_value varchar2(255);
   v_name varchar2(30);
   v_found integer:=0;
   cursor c1 is select high_value, partition_name
     from all_tab_partitions
    where table_name = i_table_name
    order by PARTITION_POSITION;
begin
   open c1;
   loop
      fetch c1 into v_value, v_name;
      exit when c1%notfound;
      if v_value = 'MAXVALUE' then
         v_found := 1;
      else
         execute immediate 'select count(*) from dual where to_date(''' || i_value || ''') <= ' || v_value
             into v_found;
      end if;
      if v_found = 1 then
         return v_name;
      end if;
   end loop;
   return ' ';
end;
/

Now, just execute this like:

select substr(GetPartitionNameRange('YOURTABLE',to_char(purchase_date,'DD-MON-YYYY')),1,10) "Partition"
, sum(amt) Total
 from YOURTABLE
group by GetPartitionNameRange('TAB1',to_char(purchase_date,'DD-MON-YYYY'))

In my test, I get:

Partition    SUM(AMT)
---------- ----------
P1                  5
P2                 10
P3                  8

 

by: awking00Posted on 2005-09-22 at 11:57:07ID: 14939470

SELECT 'P1' P_NAME, SUM(AMT) TOTAL FROM MYTABLE PARTITION(P1)
UNION
SELECT 'P2' , SUM(AMT) FROM MYTABLE PARTITION(P2)
UNION
SELECT 'P3', SUM(AMT) FROM MYTABLE PARTITION(P3);

 

by: ram_0218Posted on 2005-09-22 at 12:05:29ID: 14939535

wow!! good awking!! I never heard of this!! seems like a BEST fit to the question asked!!

 

by: tf842Posted on 2005-09-22 at 12:18:07ID: 14939632

More comments are welcome!

Awking, but we wanted to do just one query instead of multiple queries and unions, but thanks for the comment.

jrb1, your solution won't work on our tables because the number of rows and partitions would be cost/time prohibitive if using cursors. Although, on small tables/partition combinations we may use this.

Here is a sample my partner put together that loops through all the partitions, and we will use it if there is not a simple way to reference all partitions in a single query.

create table TEST_PARTITIONS
(
  PARTITION_NAME          VARCHAR2(30),
  PARTITION_POSITION  NUMBER,
  TOTAL                                   NUMBER
);


declare
  cur_table_owner   varchar2(30) := 'DBO';
  cur_table_name    varchar2(30) := 'MYTABLE';
  cur_partition            varchar2(30);
  cur_partition_num number;
  sql_str                       varchar2(2000);

begin
  loop

    select partition_name, partition_position into cur_partition, cur_partition_num from
    (select partition_name, partition_position, row_number() over(order by partition_position) r
    from all_tab_partitions
    where table_owner=cur_table_owner and table_name=cur_table_name
    and partition_name not in (select partition_name from test_partitions)
    )
    where r=1;
   
    sql_str := 'insert into TEST_PARTITIONS (partition_name, partition_position, total)
               select ''' || cur_partition || ''' partition_name, ' || cur_partition_num || ',
               sum(amt) total
               from ' || cur_table_owner || '.' || cur_table_name || ' partition(' ||
               cur_partition || ')';

    execute immediate sql_str;

    commit;

  end loop;  

  exception when no_data_found then
      null;
end;
/

We'll wait a day or so before allocating the points.

Thank you,
Sami

 

by: jrb1Posted on 2005-09-22 at 12:19:16ID: 14939638

>Partitions are occassionally added and removed. We want to create a query that will group by the current
>partitions and return their respective partition name and total.

 

by: tf842Posted on 2005-09-22 at 12:28:22ID: 14939713

All,
After reviewing all the comments,
Mark Geer's comment pretty much answwered it. We should have caught the significance of this earlier.

>>I think what makes this a challenge is the fact that Oracle implemented partitioning intentionally in a way that would not >>break existing applications at the time.  So, standard SQL statements in Oracle are not aware of the partitions.  The >>optimizer knows about them, and statements can be written that reference (or are limited to) a particular partition, but I >>don't know of a way to write one query that spans multiple partiions, yet pays attention to the partition boundaries.

In essence Mark is saying, 'The optimizer is aware of partitions but he SQL is not.'

We'll use the looping that my partner wrote. However, the points will be split as best we can.

Thank you to all who participated,
Sami

 

by: jrb1Posted on 2005-09-22 at 13:00:51ID: 14939940

I already had a final take underway.  I created a temp table:

create global temporary table current_partitions
(tblname varchar2(30), partname varchar2(30), keyval varchar2(10), position number)
on commit preserve rows;

And then loaded the current values:

 declare
    cursor c1 is select * from all_tab_partitions where table_name = 'TAB1';
    v_row c1%rowtype;
    v_key current_partitions.keyval%type;
 begin
    delete from current_partitions;
    open c1;
    loop
       fetch c1 into v_row;
       exit when c1%notfound;
       if v_row.high_value = 'MAXVALUE' then
          v_key := '9999-12-31';
       else
          v_key := substr(v_row.high_value,11,10);
       end if;
       insert into current_partitions
       values (v_row.table_name
             , v_row.partition_name
             , v_key
             , v_row.partition_position);
    end loop;
end;

Then, last did a join to bring the temp table together with the base table, determining the partition on the fly:

select partname, sum(amt)
from tab1 a
   , current_partitions b
where to_char(purchase_date,'yyyy-mm-dd') <= keyval
  and not exists (select 1 from current_partitions where
                    to_char(purchase_date,'yyyy-mm-dd') <= keyval
                       and keyval < b.keyval)
group by partname;

 

by: awking00Posted on 2005-09-22 at 13:39:48ID: 14940214

I know poinst have already been awarded but you may want to consider this.
>>but we wanted to do just one query instead of multiple queries and unions<<
A union is a single query, it's like a join without the join conditions. At any rate, you can still apply the methodology in a procedure as follows:

create or replace procedure insert_part_sums is

num_partitions   number;
count_partitions number := 1;
sql_str  varchar2(2000) := 'insert into test_partitions ';

begin

select count(*)
into num_partitions
from all_tab_partitions
 where table_owner = <schema_name>
 and table_name = 'MYTABLE';

for part_rec in
(select partition_name, partition_position
 from all_tab_partitions
 where table_owner = <schema_name>
 and table_name = 'MYTABLE')
loop

sql_str := sql_str||' select '||part_rec.partition_name||','
                              ||part_rec.partition_position
                  ||', sum(amt) total from mytable partition('
                  ||part_rec.partition_name||') ';

count_partitions := count_partitions + 1;
if count_partitions < num_partitions then
sql_str := sql_str||'union ';
end if;

end loop;

execute immediate sql_str;

end;

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...