Skip to Main Content
  • Questions
  • Want to use single select statement instead of various union all's for fetching previous quarter data

Breadcrumb

Question and Answer

Connor McDonald

Thanks for the question, Mohit.

Asked: August 31, 2018 - 6:38 pm UTC

Last updated: September 08, 2018 - 10:16 am UTC

Version: 11g

Viewed 1000+ times

You Asked

I have 5 select statements using union all(showing a few in here)
want to use a single statement to fetch the revenue from a table .
So based on the condition that AND period_id>=1009
AND Opp_Created_Date_Period_Id<=1009(for every previous quarters
where 1009 means yr 2018 Q2(also data contained in dim quater table looks like this only)
1008 - yr18 Q1
1007 - yr 17 Q4 (quarters)
and so on.
-want to fetch previous quarters .revenue
-most importantly period_id and Opp_Created_Date_Period_Id is to be compared separetly to each quarter separatly to produce its revenue.,for that quarter
-this period id value goes on decreasing up to five previous quarters
-these are parameters only

SELECT T1.PERIOD,NVL(Sum(Source_Rev),0) "SOURCE_REV"  FROM MA_DIM_QUATER_DATA_TEST  T1 LEFT JOIN
(
Select Sum(REVENUE_SHARE) As "SOURCE_REV" ,MIN(period_id) as PERIOD From Ma_Fact_Revenue_test  
Where  is_sourced!='Sourced'
AND (GEO_ID=0 OR 0=0)
AND ( Strategic_Initiative_Id IN (0) OR ( COALESCE(NULL, 0))=0)
AND period_id>=1009  
AND Opp_Created_Date_Period_Id<=1009

UNION ALL
Select Sum(REVENUE_SHARE) As "SOURCE_REV",MIN(period_id) as PERIOD From Ma_Fact_Revenue_test   
Where  is_sourced!='Sourced'
AND (GEO_ID=0 OR 0=0)
AND ( Strategic_Initiative_Id IN (0) OR ( COALESCE(NULL, 0))=0)
AND period_id>=1009-1   
AND Opp_Created_Date_Period_Id<=1009-1

UNION ALL
Select Sum(REVENUE_SHARE) As "SOURCE_REV",MIN(period_id) AS  PERIOD  From Ma_Fact_Revenue_test   
Where  is_sourced!='Sourced'
AND (GEO_ID=0 OR 0=0)
AND ( Strategic_Initiative_Id IN (0) OR ( COALESCE(NULL, 0))=0)
AND period_id>=1009-2  
AND Opp_Created_Date_Period_Id<=1009-2

UNION ALL

Select Sum(REVENUE_SHARE) As "SOURCE_REV",MIN(period_id) as PERIOD  From Ma_Fact_Revenue_test   
Where  is_sourced!='Sourced'
AND (GEO_ID=0 OR 0=0)
AND ( Strategic_Initiative_Id IN (0) OR ( COALESCE(NULL, 0))=0)
AND period_id>=1009-3  
AND Opp_Created_Date_Period_Id<=1009-3

UNION ALL
Select NVL(Sum(REVENUE_SHARE),0) As "SOURCE_REV" ,MIN(period_id) as "PERIOD" From Ma_Fact_Revenue_test   
Where  is_sourced!='Sourced'
AND (GEO_ID=0 OR 0=0)
AND ( Strategic_Initiative_Id IN (0) OR ( COALESCE(NULL, 0))=0)
AND period_id>=1009-4  
AND Opp_Created_Date_Period_Id<=1009-4
)T2 ON t1.id =t2.period
where t1.id in (1009,1009-1,1009-2,1009-3,1009-4)
GROUP BY t1.period
order by t1.period

and Connor said...

Just focussing on T2, the following predicates are always true:

AND (GEO_ID=0 OR 0=0)
AND ( Strategic_Initiative_Id IN (0) OR ( COALESCE(NULL, 0))=0)


and the following is common to all queries

Where  is_sourced!='Sourced'


So can't this be reduced to:

(
Select Sum(REVENUE_SHARE) As "SOURCE_REV" ,MIN(period_id) as PERIOD From Ma_Fact_Revenue_test  
Where  is_sourced!='Sourced'
AND 
(
  ( period_id>=1009  AND Opp_Created_Date_Period_Id<=1009 )
or
  ( period_id>=1009-1 AND Opp_Created_Date_Period_Id<=1009-1 )
or
 ( period_id>=1009-2   AND Opp_Created_Date_Period_Id<=1009-2 )
or 
 ( period_id>=1009-3   AND Opp_Created_Date_Period_Id<=1009-3 )
or 
 ( period_id>=1009-4   AND Opp_Created_Date_Period_Id<=1009-4 )
) 


Rating

  (7 ratings)

Is this answer out of date? If it is, please let us know via a Comment

Comments

A reader, September 03, 2018 - 5:19 am UTC

-Hi
Thanks for the response
The query given by you is giving me the revenue and share of the min period of all which is 1009-4.
But what i wanted is like this

min period of ( period_id>=1009 AND Opp_Created_Date_Period_Id<=1009 ) --->1009 and revenue from this condition

min period of ( period_id>=1009-1 AND Opp_Created_Date_Period_Id<=1009 ) --->1008 and revenue from this condition
and so on.

since if use group by min(period), it cant be done as aggregate functions are not allowed in group by clause.


(
Select Sum(REVENUE_SHARE) As "SOURCE_REV" ,MIN(period_id) as PERIOD From Ma_Fact_Revenue_test
Where is_sourced!='Sourced'
AND
(
( period_id>=1009 AND Opp_Created_Date_Period_Id<=1009 )
or
( period_id>=1009-1 AND Opp_Created_Date_Period_Id<=1009-1 )
or
( period_id>=1009-2 AND Opp_Created_Date_Period_Id<=1009-2 )
or
( period_id>=1009-3 AND Opp_Created_Date_Period_Id<=1009-3 )
or
( period_id>=1009-4 AND Opp_Created_Date_Period_Id<=1009-4 )
)
Connor McDonald
September 04, 2018 - 5:32 am UTC

Ah... I see what you mean. I need some more data - are the 4 union-all's mutually exclusive? ie, could a single row sit in more than one of them ?

A reader, September 03, 2018 - 5:39 am UTC

Hi

Thanks for the response.

The query given by is(Select Sum(REVENUE_SHARE) As "SOURCE_REV" ,MIN(period_id) as PERIOD From Ma_Fact_Revenue_test
Where is_sourced!='Sourced'
AND
(
( period_id>=1009 AND Opp_Created_Date_Period_Id<=1009 )
or
( period_id>=1009-1 AND Opp_Created_Date_Period_Id<=1009-1 )
--
--
( period_id>=1009-4 AND Opp_Created_Date_Period_Id<=1009-4 )
and so on)

is providing me the revenue of the min period_id of all which is 1009-4

But what i wanted is like this:

min period of (Period_Id>=1009
AND Opp_Created_Date_Period_Id<=1009)
which is 1009 and its revenue


min period of (Period_Id >=1009-1
AND Opp_Created_Date_Period_Id<=1009-1)
which is 1008 and its revenue

and so on.

And the problem is i cant use group by with min (period),as its not allowed.

Hope it clarifies my requirement

Mohit, September 03, 2018 - 5:52 am UTC

Hi

Thanks for the response.

The query given by is(Select Sum(REVENUE_SHARE) As "SOURCE_REV" ,MIN(period_id) as PERIOD From Ma_Fact_Revenue_test
Where is_sourced!='Sourced'
AND
(
( period_id>=1009 AND Opp_Created_Date_Period_Id<=1009 )
or
( period_id>=1009-1 AND Opp_Created_Date_Period_Id<=1009-1 )
--
--
( period_id>=1009-4 AND Opp_Created_Date_Period_Id<=1009-4 )
and so on)

is providing me the revenue of the min period_id of all which is 1009-4

But what i wanted is like this:

min period of (Period_Id>=1009
AND Opp_Created_Date_Period_Id<=1009)
which is 1009 and its revenue


min period of (Period_Id >=1009-1
AND Opp_Created_Date_Period_Id<=1009-1)
which is 1008 and its revenue

and so on.

And the problem is i cant use group by with min (period),as its not allowed.

Hope it clarifies my requirement

Followup-reply

Mohit, September 05, 2018 - 9:45 am UTC

Hi Connor

Yes the data from union all's might be mutually exclusive
revenue of one quarter can come in another.
since i have used period_id >1009(Q2) and later >1008(Q1) and so on.


Connor McDonald
September 06, 2018 - 1:07 am UTC

"Yes the data from union all's might be mutually exclusive"

So I should infer this as:

"No, the data is NOT mutually exclusive" ?


Followup-reply

A reader, September 06, 2018 - 5:26 am UTC

No they are mutually exclusive i.e one row can sit in another union
Connor McDonald
September 08, 2018 - 10:16 am UTC

No they are mutually exclusive i.e one row can sit in another union

mutual exclusive means that can NOT sit in another union

So which is it ?

Followup-reply

Mohit, September 10, 2018 - 6:18 am UTC

Oh i See,so finally i would say that they are NOT mutually exclusive(since one row might sit in another union all).

Followup-reply

A reader, September 12, 2018 - 10:20 am UTC

Hi Connor,

Can i get any update on this pls??

More to Explore

Performance

Get all the information about database performance in the Database Performance guide.