使用 CASE 和 generate_series() 查询,将结果 timestamptz 降序排列
Query with CASE and generate_series(), order resulting timestamptz descending
我是新手,正在尝试使用以下代码创建函数:
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$;
上面查询的结果是:
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
我尝试使用 order by desc
和 order by timestamp desc
但它不起作用。我想按降序排列,所以我得到了从 2017-07-01 到 2017-01-01 的结果。我该怎么做?
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 time_st order by time_st desc
输出:
2017-07-01 00:00:00+05:30
2017-06-01 00:00:00+05:30
2017-05-01 00:00:00+05:30
2017-04-01 00:00:00+05:30
2017-03-01 00:00:00+05:30
2017-02-01 00:00:00+05:30
2017-01-01 00:00:00+05:30
您有两种方法可以做到这一点:
添加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$;
或者当你从其他地方调用它时,你可以从过程和订单中删除排序:
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$;
并调用:
select request_detail from public.get_bulan() order by request_detail desc
注意:第二个非常柔韧,您可以轻松操作。
您的 SQL CASE
语句的第一个和最后一个分支 return 行按降序排列,其他两个按升序排列。因此,您需要在外部 SELECT
.
中添加另一个 ORDER BY
彻底的解决方法是使所有 4 个分支 return 行的顺序相同。
或者更确切地说,完全重写它以理清混乱:
SELECT *
FROM generate_series(
CASE
WHEN extract(DAY FROM now()) >= 25 THEN date_trunc('month', now())
WHEN extract(MONTH FROM now()) <= 2 THEN now()
ELSE now() - interval '1 month'
END
, date_trunc('year' , now())
, interval '- 1 month' -- negative interval
) t(request_detail)
ORDER BY request_detail DESC; -- redundant
负区间自动降序排列。您可以添加 ORDER BY request_detail DESC
以明确和正确标准 SQL.
如果愿意,可以将查询包装到一个函数中。
最重要的是,不要 将 set-returning 函数像 generate_series()
包装在 CASE
语句。这从来都不是一个好主意,但从 Postgres 10 开始它会引发错误:
ERROR: set-returning functions are not allowed in CASE
演示:
dbfiddle here
我是新手,正在尝试使用以下代码创建函数:
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$;
上面查询的结果是:
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
我尝试使用 order by desc
和 order by timestamp desc
但它不起作用。我想按降序排列,所以我得到了从 2017-07-01 到 2017-01-01 的结果。我该怎么做?
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 time_st order by time_st desc
输出:
2017-07-01 00:00:00+05:30
2017-06-01 00:00:00+05:30
2017-05-01 00:00:00+05:30
2017-04-01 00:00:00+05:30
2017-03-01 00:00:00+05:30
2017-02-01 00:00:00+05:30
2017-01-01 00:00:00+05:30
您有两种方法可以做到这一点:
添加
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$;
或者当你从其他地方调用它时,你可以从过程和订单中删除排序:
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$;
并调用:
select request_detail from public.get_bulan() order by request_detail desc
注意:第二个非常柔韧,您可以轻松操作。
您的 SQL CASE
语句的第一个和最后一个分支 return 行按降序排列,其他两个按升序排列。因此,您需要在外部 SELECT
.
ORDER BY
彻底的解决方法是使所有 4 个分支 return 行的顺序相同。
或者更确切地说,完全重写它以理清混乱:
SELECT *
FROM generate_series(
CASE
WHEN extract(DAY FROM now()) >= 25 THEN date_trunc('month', now())
WHEN extract(MONTH FROM now()) <= 2 THEN now()
ELSE now() - interval '1 month'
END
, date_trunc('year' , now())
, interval '- 1 month' -- negative interval
) t(request_detail)
ORDER BY request_detail DESC; -- redundant
负区间自动降序排列。您可以添加 ORDER BY request_detail DESC
以明确和正确标准 SQL.
如果愿意,可以将查询包装到一个函数中。
最重要的是,不要 将 set-returning 函数像 generate_series()
包装在 CASE
语句。这从来都不是一个好主意,但从 Postgres 10 开始它会引发错误:
ERROR: set-returning functions are not allowed in CASE
演示:
dbfiddle here