Want to win a PS4? Go Premium and enter to win our High-Tech Treats giveaway. Enter to Win

x
?
Solved

ReportSQLQuerry_SumingQtyShipped

Posted on 2011-03-07
14
Medium Priority
?
409 Views
Last Modified: 2012-05-11
STOCK_ITEMS

NAME                   type
------------------------------------------------------------------------
STOCK_NUMBER            VARCHAR2(20)
.......


SHIPMENT

Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
SHIPMENT_ID                               NOT NULL NUMBER(10)
ORDER_NO                                           NUMBER(10)
SHIPMENT_DATE                                      DATE
SHIP_FROM_ORG                                      VARCHAR2(8)
SHIP_TO_ORG                                        VARCHAR2(8)
...


SHIPPED_ITEMS

Name                                      Null?    Type
----------------------------------------- -------- ----------------------------
SHIPMENT_ID                               NOT NULL NUMBER(10)
STOCK_NUMBER                              NOT NULL VARCHAR2(20)
ITEM_NUMBER                               NOT NULL NUMBER(2)
QUANTITY_SHIPPED                                   NUMBER(8)
SHIPCODE                                           VARCHAR2(1)
created_date                                       DATE


I have the above 3 tables.

I need to report on 1 month, 6 month, 1 year, 2 year, 5 year and 10 year usage for each stock item. This is the total quantity shipped in each period. How would you write the SQL for that. Would you use subquery for each calculation and include that in main query like this or that would be slow and it better to do the whole clculations in one scan using CASE.

select stock_number, (query1) 1_mon, (query2) 6_mon, (query3) 1_yr, (query 4) 2_yr, (query5) 5_yr from stock_item;

query1 = select sum(quantity_shipped) from shipped_item a WHERE created date between trunc(sysdate) and trunc(sysdate-30);
0
Comment
Question by:sam15
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
14 Comments
 
LVL 101

Expert Comment

by:mlmcc
ID: 35065792
Not a Crystal Reports question

mlmcc
Zone Advisor
0
 
LVL 4

Expert Comment

by:pinkuray
ID: 35077880
You can go with Reporting aggregate functions in oracle which gives you the result for yearly , monthly and quarterly report like to get the details on sales or stocks quantity report:

check this link hope this will give all what you are trying to get:

http://www.orafusion.com/art_anlytc.htm 
0
 
LVL 4

Accepted Solution

by:
subratabiswas earned 2000 total points
ID: 35078295
with joined_table as (select stock_items.stock_number, shipment.shipment_date, shipped_items.quantity_shipped
                          from shipment, shipped_items, stock_items
                          where shipped_items.shipment_id = shipment.shipment_id
                            and stock_items.stock_number = shipped_items.stock_number),
      one_month_sum as (select stock_number, sum(quantity_shipped) as qty
                            from joined_table
                            where shipment_date > add_months(sysdate, -1)
                            group by stock_number),
      six_month_sum as (select stock_number, sum(quantity_shipped)  as qty
                            from joined_table
                            where shipment_date > add_months(sysdate, -6)
                            group by stock_number),
      one_year_sum as (select stock_number, sum(quantity_shipped) as qty
                            from joined_table
                            where shipment_date > add_months(sysdate, -12)
                            group by stock_number),
      two_year_sum as (select stock_number, sum(quantity_shipped) as qty
                            from joined_table
                            where shipment_date > add_months(sysdate, -24)
                            group by stock_number),
      five_year_sum as (select stock_number, sum(quantity_shipped) as qty
                            from joined_table
                            where shipment_date > add_months(sysdate, -60)
                            group by stock_number),
      ten_year_sum as (select stock_number, sum(quantity_shipped) as qty
                            from joined_table
                            where shipment_date > add_months(sysdate, -120)
                            group by stock_number)
select stock_items.stock_number,
       sum(one_month_sum.qty) as one_month_sum,
       sum(six_month_sum.qty) as six_month_sum,
       sum(one_year_sum.qty) as one_year_sum,
       sum(two_year_sum.qty) as two_year_sum,
       sum(five_year_sum.qty) as five_year_sum,
       sum(ten_year_sum.qty) as ten_year_sum
    from stock_items, one_month_sum, six_month_sum, one_year_sum, two_year_sum, five_year_sum, ten_year_sum
    where one_month_sum.stock_number(+) = stock_items.stock_number
      and six_month_sum.stock_number(+) = stock_items.stock_number
      and one_year_sum.stock_number(+) = stock_items.stock_number
      and two_year_sum.stock_number(+) = stock_items.stock_number
      and five_year_sum.stock_number(+) = stock_items.stock_number
      and ten_year_sum.stock_number(+) = stock_items.stock_number group by stock_items.stock_number
0
Windows Server 2016: All you need to know

Learn about Hyper-V features that increase functionality and usability of Microsoft Windows Server 2016. Also, throughout this eBook, you’ll find some basic PowerShell examples that will help you leverage the scripts in your environments!

 

Author Comment

by:sam15
ID: 35078372
is this ansi sql above. we use regular sql and joins in all applications. can you rewrite using normal sql.
0
 
LVL 4

Expert Comment

by:subratabiswas
ID: 35078510
This is Oracle Syntax
0
 

Author Comment

by:sam15
ID: 35078658
kind of stange. i thought it is more of the ansi format we dont use.

Is this doing subqueries with full scan for each subquery? what index columns would help here.
0
 
LVL 4

Expert Comment

by:subratabiswas
ID: 35080450
Resultset from the 1st sub-query shold be used in all the subsequent ones. Tuning this query will be a separate activity, but can be started by creating index on the columns used in the WHERE clauses and the GROUP BY clause. Try to see the effect of the indices by executing sql trace.
0
 

Author Comment

by:sam15
ID: 35100588
Query works fine. I tested it.

just a quick would you use SYSDATE or TRUNC(SYDATE) to go for full days instead of partials?

Also, do you ecommend to use CREATED_DATE for record in case user made a data entry error in shipment date.
0
 
LVL 4

Expert Comment

by:subratabiswas
ID: 35114494
Yes, applying TRUNC function will return data for the few extra hours to include the period from the beginning of the day. FYI, by default TRUNC would round the time to the beginning of the day, but there are different (optional) formatting options to round it on different period (MONTH, YEAR etc.)

Whether to use CREATED_DATE or SHIPMENT_DATE, will depend on the application. It is possible that CREATED_DATE is maintained programatically and is free from any human data entry error. From that point of view, it appears preferable. But it is also possible that the data is being entered in batch or by a data entry operation at a time different from the actual shipment time. In that scenario, if someone wants to track the shipment by the actual time of shipping, he may not be interested in the CREATED_DATE. We are talking of two times, one when the shipping actually took place, and the other when the shipping record was entered into the system. Depending on the application, there may or may not be significant gap between them. Some users may ignore that gap, while others may be interested in one or the other. I guess, both the dates are maintained considering utility of both of them.
0
 

Author Comment

by:sam15
ID: 35116151
TRUNC(SYSDATE) will exclude all transaction that happened today. It will stop all activity at yesterday midnight. so when users run report today 10 times it will yield same result. I think this is cleaner instead of using SYSDATE which will use part of today and part of the day 30 or 60 days ago.
do you agree?

The only think is i would need to create an  a function based index INDEX on TRUNC(SHIPMENT_DATE).

we currently dont have any validation on shipment date nor any batch job. It is safer to use created_date which is automatically entered by system.


I am not sure why you used GROUP BY in your last query for result. The tables were grouped in your query for each before. is there anything i missed.

select stock_items.stock_number,
       sum(one_month_sum.qty) as one_month_sum,
       sum(six_month_sum.qty) as six_month_sum,
       sum(one_year_sum.qty) as one_year_sum,
       sum(two_year_sum.qty) as two_year_sum,
       sum(five_year_sum.qty) as five_year_sum,
       sum(ten_year_sum.qty) as ten_year_sum
    from stock_items, one_month_sum, six_month_sum, one_year_sum, two_year_sum, five_year_sum, ten_year_sum
0
 
LVL 4

Expert Comment

by:subratabiswas
ID: 35118325
1) Last GROUP BY is required because the query is using AGGREGATE function
2) Effect of TRUNC on duration may change depending on where the function is being applied (before applying other functions like ADD_MONTHS etc, or after the function call).
0
 

Author Comment

by:sam15
ID: 35118697
The reason i asked you about the aggregate is i have a few other columns from STOCK_ITEMS table to select like STOCK_DESCRIPTIO, UNITS, etc.

I do not want to select those in the aggregate function and group by them.

I am thinking to add another subquery and join that.

I have to test this but my thinking is that you already have aggregates in ONE_MONTH_SUM, SIX_MONTH_SUM. there should be one stock number, quantity.
So when you join it tothe main stock items fields it should be ONE to ONE join.

 
0
 
LVL 4

Expert Comment

by:subratabiswas
ID: 35119657
Yes, it should be possible to remove the aggregate (SUM and GROUP BY) on the final query, as the aggregate is already done at the feeding sub-query level. Along with the in-line views, another instance of STOCK_ITEMS can also be added to select other desired attributes from that table.
0
 

Author Closing Comment

by:sam15
ID: 35134837
Excellent answer!
0

Featured Post

Visualize your virtual and backup environments

Create well-organized and polished visualizations of your virtual and backup environments when planning VMware vSphere, Microsoft Hyper-V or Veeam deployments. It helps you to gain better visibility and valuable business insights.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

If you find yourself in this situation “I have used SELECT DISTINCT but I’m getting duplicates” then I'm sorry to say you are using the wrong SQL technique as it only does one thing which is: produces whole rows that are unique. If the results you a…
I'm trying, I really am. But I've seen so many wrong approaches involving date(time) boundaries I despair about my inability to explain it. I've seen quite a few recently that define a non-leap year as 364 days, or 366 days and the list goes on. …
This video shows syntax for various backup options while discussing how the different basic backup types work.  It explains how to take full backups, incremental level 0 backups, incremental level 1 backups in both differential and cumulative mode a…
This video explains what a user managed backup is and shows how to take one, providing a couple of simple example scripts.

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question