One way is to use conditional aggregation together with row_number():
select sales_period,
max(case when seqnum = 1 then opening_amt end) as opening_amt,
sum(sales_amt) as sales_amt,
sum(payment_amt) as payment_amt,
max(case when seqnum = 1 then closing_amt end) as closing_amt
from (select bd.*,
row_number() over (partition by sales_period order sales_date desc) as seqnum
from balance_detail bd
) bd
group by sales_period;
source
share