From multiple tables I'm currently selecting a product, value, and contract period. I want to group the results by product and shipment period while summing the value.
My contract period can either be arrival based or shipment based. So, currently to determine which contract period to use, I'm looking to see if one of the period descriptions is null then populating the period end and begin dates as either ship or arrival based on that. Specifically, I'm using the following.
DECODE((P.SHIP_PERIOD_DESCR), NULL,
'ARRIVE' || ' ' ||P.ARRIVAL_PERIOD_BEGIN || ' - ' || P.ARRIVAL_PERIOD_END,
'SHIP' || ' ' ||P.SHIP_PERIOD_BEGIN || ' - ' || P.SHIP_PERIOD_END)
My results are as such:
PRODUCT VALUE CONTRACT_PERIOD
APPLES $600 SHIP 01-FEB-16 - 15-MAR-16
APPLES $700 SHIP 01-MAR-16 - 15-APR-16
LEMONS $200 SHIP 15-JAN-16 - 31-JAN-16
LEMONS $150 SHIP 01-FEB-16 - 15-FEB-16
LEMONS $200 ARRIVE 15-FEB-16 - 28-FEB-16
LEMONS $250 ARRIVE 01-MAR-16 - 15-MAR-16
What I would like to see is the min ship or arrival date and max ship or arrival date per product as such:
PRODUCT VALUE CONTRACT_PERIOD
APPLES $1,300 SHIP 01-FEB-16 - 15-APR-16
LEMONS $350 SHIP 15-JAN-16 - 15-FEB-16
LEMONS $450 ARRIVE 15-FEB-16 - 15-MAR-16
Any suggestions on a way to determine which contract is valid, then group the results using the min and max dates while not interchanging a ship date for an arrival date would be greatly appreciated.
The basic idea is not to combine the different columns into a single concatenated column. Then use intelligent aggregation:
with t as (
<basically your query here, but with each column individually>
)
select product, ship_period_desc,
min(case when ship_period_desc = 'ARRIVAL' then ARRIVAL_PERIOD_BEGIN
else SHIP_PERIOD_BEGIN
end) as PERIOD_BEGIN,
min(case when ship_period_desc = 'ARRIVAL' then ARRIVAL_PERIOD_END
else SHIP_PERIOD_END
end) as PERIOD_END
from t
where ship_period_desc in ('ARRIVAL', 'SHIP')
group by product, ship_period_desc;
Oracle Setup :
CREATE TABLE table_name ( product, value, ship_period_descr, arrival_period_begin, arrival_period_end, ship_period_begin, ship_period_end ) AS
SELECT 'Apples', 600, 'X', NULL, NULL, DATE '2016-02-01', DATE '2016-03-15' FROM DUAL UNION ALL
SELECT 'Apples', 700, 'X', NULL, NULL, DATE '2016-03-01', DATE '2016-04-16' FROM DUAL UNION ALL
SELECT 'Lemons', 200, 'X', NULL, NULL, DATE '2016-01-15', DATE '2016-01-31' FROM DUAL UNION ALL
SELECT 'Lemons', 150, 'X', NULL, NULL, DATE '2016-02-01', DATE '2016-02-15' FROM DUAL UNION ALL
SELECT 'Lemons', 200, NULL, DATE '2016-02-15', DATE '2016-02-28', NULL, NULL FROM DUAL UNION ALL
SELECT 'Lemons', 250, NULL, DATE '2016-03-01', DATE '2016-03-15', NULL, NULL FROM DUAL;
Query :
SELECT Product,
SUM( Value ) AS Value,
DECODE(
DECODE( P.SHIP_PERIOD_DESCR, NULL, 1, 0 ),
1, 'ARRIVE ' || MIN( P.ARRIVAL_PERIOD_BEGIN ) || ' - ' || MAX( P.ARRIVAL_PERIOD_END ),
'SHIP ' || MIN( P.SHIP_PERIOD_BEGIN ) || ' - ' || MAX( P.SHIP_PERIOD_END )
) AS Contract_Period
FROM table_name p
GROUP BY Product,
DECODE( P.SHIP_PERIOD_DESCR, NULL, 1, 0 );
Results :
PRODUCT VALUE CONTRACT_PERIOD
------- ---------- ----------------------------------------------
Apples 1300 SHIP 01-FEB-16 - 16-APR-16
Lemons 350 SHIP 15-JAN-16 - 15-FEB-16
Lemons 450 ARRIVE 15-FEB-16 - 15-MAR-16
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.