Q:

Query with CASE and generate_series(), order resulting timestamptz descending

I'm new and trying to create a function with the following code:
CREATE OR REPLACE FUNCTION public.get_bulan()
returns table (request_detail timestamp with time zone)
language plpgsql stable
as $function$
        begin
        return query

        select
        case
        when (extract(DAY FROM now()) >= 25) then generate_series(date_trunc('year', now()), date_trunc('day', now()) ,interval '1 month')
        when (select extract(month FROM now()) = 2) then now() - (interval '1' month * generate_series(0,1))
        when (select extract(month FROM now()) = 1) then now() - (interval '1' month * generate_series(0,2))
        else generate_series((select date(date_trunc('year', now()))), (select date(now())-'1 month'::interval), interval '1 month')
        end
        order by timetstamptz(request_detail) desc;
        end;
        $function$;

The result from the query above is:
2017-01-01 00:00:00
2017-02-01 00:00:00
2017-03-01 00:00:00
2017-04-01 00:00:00
2017-05-01 00:00:00
2017-06-01 00:00:00
2017-07-01 00:00:00

I tried using order by desc and order by timestamp desc but it doesn't work.  I want to make the order by descending so I get the result from 2017-07-01 to 2017-01-01.  How do I do that? 

A:

You have two ways to do that:

Add as result_timestamp order by result_timestamp desc;
CREATE OR REPLACE FUNCTION public.get_bulan()
 returns table (request_detail timestamp with time zone)
 language plpgsql stable
 as $function$
    begin
    return query

    select 
    case
    when (extract(DAY FROM now()) >= 25) then generate_series(date_trunc('year', now()), date_trunc('day', now()) ,interval '1 month')
    when (select extract(month FROM now()) = 2) then now() - (interval '1' month * generate_series(0,1))
    when (select extract(month FROM now()) = 1) then now() - (interval '1' month * generate_series(0,2))
    else generate_series((select date(date_trunc('year', now()))), (select date(now())-'1 month'::interval), interval '1 month')
    end as result_timestamp order by result_timestamp desc;

    end;
    $function$;

Alternatively you can delete ordering from procedure and order when u call it from other place:
CREATE OR REPLACE FUNCTION public.get_bulan()
returns table (request_detail timestamp with time zone)
language plpgsql stable
as $function$
        begin
        return query

        select 
        case
        when (extract(DAY FROM now()) >= 25) then generate_series(date_trunc('year', now()), date_trunc('day', now()) ,interval '1 month')
        when (select extract(month FROM now()) = 2) then now() - (interval '1' month * generate_series(0,1))
        when (select extract(month FROM now()) = 1) then now() - (interval '1' month * generate_series(0,2))
        else generate_series((select date(date_trunc('year', now()))), (select date(now())-'1 month'::interval), interval '1 month')
        end;

        end;
        $function$;

And calling: 
select request_detail from public.get_bulan() order by request_detail desc

NOTE: the second one is much pliable and you can easily manipulate.