Oracle FAQ | Your Portal to the Oracle Knowledge Grid |
![]() |
![]() |
Home -> Community -> Usenet -> c.d.o.server -> Re: Oracle query assistence
On Nov 13, 7:46 pm, trp..._at_gmail.com wrote:
> I have a table defined as follows:
>
> CREATE TABLE products
> (
> report_date DATE not null,
> product_name varchar2(128) not null,
> num_cases number(4) not null,
> CONSTRAINT peoplesoftProduct_pk PRIMARY KEY (report_date,
> product_name)
> );
>
> Here is a query I am running that produces the data I am after:
>
> SELECT PRODUCT_NAME, NUM_CASES,
> to_char(REPORT_DATE,'Mon YYYY') AS "Report Date"
> FROM PRODUCTS
> WHERE PRODUCT_NAME IN ('Product1', 'Product2')
> AND report_date < to_date ('2007-09-30','YYYY-MM-DD')
> AND report_date > to_date ('2007-09-30','YYYY-MM-DD') - 365
> ORDER BY PRODUCT_NAME ASC, REPORT_DATE ASC
>
> Here is the output:
>
> PRODUCT_NAME NUM_CASES Report Date
> Product1 429 Nov 2006
> Product1 238 Dec 2006
> Product1 304 Jan 2007
> Product1 284 Feb 2007
> Product1 271 Mar 2007
> Product1 352 Apr 2007
> Product1 422 May 2007
> Product1 242 Jun 2007
> Product1 220 Jul 2007
> Product1 211 Aug 2007
> Product1 247 Sep 2007
> Product2 176 Nov 2006
> Product2 152 Dec 2006
> Product2 157 Jan 2007
> Product2 126 Feb 2007
> Product2 139 Mar 2007
> Product2 156 Apr 2007
> Product2 206 May 2007
> Product2 206 Jun 2007
> Product2 262 Jul 2007
> Product2 213 Aug 2007
> Product2 187 Sep 2007
>
> The way I actually want the data to display from a query is as
> follows:
>
> Nov 2006 Dec 2006 Jan
> 2007 ...
> Product1 429 238 304 ...
> Product2 176 152 157 ...
>
> Now I know I could use the above query and write a script to process
> the data to make it output as I wish, but I really want to do this in
> a query. Is this possible and how would I adapt the above query to do
> so?
>
> Thanks!
Let's take a look to see if there are ways to create cross-tab style reports.
First, an experiment to see if we can have Oracle count the months,
starting with a particular month start date:
SELECT
LEVEL POSITION,
ADD_MONTHS(TO_DATE('2007-10-01','YYYY-MM-DD') - 365, LEVEL-1)
MONTH_START
FROM
DUAL
CONNECT BY
LEVEL<=12;
POSITION MONTH_STA
---------- --------- 1 01-OCT-06 2 01-NOV-06 3 01-DEC-06 4 01-JAN-07 5 01-FEB-07 6 01-MAR-07 7 01-APR-07 8 01-MAY-07 9 01-JUN-07 10 01-JUL-07 11 01-AUG-07 12 01-SEP-07
Now that we see that is possible, we should be able to use a
combination of MAX, DECODE, and GROUP BY to develop a solution.
First, the set up:
CREATE TABLE T1 (
REPORT_DATE DATE,
PRODUCT_NAME VARCHAR2(128),
NUM_CASES NUMBER(4));
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',429,'01-NOV-2006');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',238,'01-DEC-2006');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',304,'01-JAN-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',284,'01-FEB-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',271,'01-MAR-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',352,'01-APR-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',422,'01-MAY-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',242,'01-JUN-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',220,'01-JUL-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',211,'01-AUG-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product1',247,'01-SEP-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',176,'01-NOV-2006');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',152,'01-DEC-2006');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',157,'01-JAN-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',126,'01-FEB-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',139,'01-MAR-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',156,'01-APR-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',206,'01-MAY-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',206,'01-JUN-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',262,'01-JUL-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',213,'01-AUG-2007');
INSERT INTO T1 (PRODUCT_NAME, NUM_CASES, REPORT_DATE) VALUES
('Product2',187,'01-SEP-2007');
Now, let's take the SQL statement that we previously used above and
join it to a simple select statement with our T1 table - we will slide
each into an inline view:
SELECT
T.PRODUCT_NAME, T.REPORT_DATE, T.NUM_CASES, C.POSITION
-------- --------- ---------- ---------- Product1 01-NOV-06 429 2 Product1 01-DEC-06 238 3 Product1 01-JAN-07 304 4 Product1 01-FEB-07 284 5 Product1 01-MAR-07 271 6 Product1 01-APR-07 352 7 Product1 01-MAY-07 422 8 Product1 01-JUN-07 242 9 Product1 01-JUL-07 220 10 Product1 01-AUG-07 211 11 Product1 01-SEP-07 247 12 Product2 01-NOV-06 176 2 Product2 01-DEC-06 152 3 Product2 01-JAN-07 157 4 Product2 01-FEB-07 126 5 Product2 01-MAR-07 139 6 Product2 01-APR-07 156 7 Product2 01-MAY-07 206 8 Product2 01-JUN-07 206 9 Product2 01-JUL-07 262 10 Product2 01-AUG-07 213 11 Product2 01-SEP-07 187 12
You will likely note that there is now a counter next to each row from
the T1 table - we will use this with DECODE, MAX and GROUP BY to
collapse all rows for a single PRODUCT_NAME into a single row, and
place each of the NUM_CASES into a separate column based on the value
of POSITION:
SELECT
T.PRODUCT_NAME,
MAX(DECODE(C.POSITION,1,T.NUM_CASES,NULL)) P1, MAX(DECODE(C.POSITION,2,T.NUM_CASES,NULL)) P2, MAX(DECODE(C.POSITION,3,T.NUM_CASES,NULL)) P3, MAX(DECODE(C.POSITION,4,T.NUM_CASES,NULL)) P4, MAX(DECODE(C.POSITION,5,T.NUM_CASES,NULL)) P5, MAX(DECODE(C.POSITION,6,T.NUM_CASES,NULL)) P6, MAX(DECODE(C.POSITION,7,T.NUM_CASES,NULL)) P7, MAX(DECODE(C.POSITION,8,T.NUM_CASES,NULL)) P8, MAX(DECODE(C.POSITION,9,T.NUM_CASES,NULL)) P9, MAX(DECODE(C.POSITION,10,T.NUM_CASES,NULL)) P10, MAX(DECODE(C.POSITION,11,T.NUM_CASES,NULL)) P11, MAX(DECODE(C.POSITION,12,T.NUM_CASES,NULL)) P12FROM
Product1 429 238 211 247 Product2 176 152 213 187
There are of course other ways to accomplish the above - this is just
one method. If you search this group (or the other
comp.databases.oracle.x groups) using Google, you will likely find
other examples, including this one:
http://groups.google.com/group/comp.databases.oracle.misc/browse_thread/thread/b06766c6871b698b
Charles Hooper
IT Manager/Oracle DBA
K&M Machine-Fabricating, Inc.
Received on Wed Nov 14 2007 - 06:14:52 CST
![]() |
![]() |