gpt4 book ai didi

sql - 从 select 语句推断的 Postgres 隐式类型

转载 作者:行者123 更新时间:2023-11-29 14:23:41 25 4
gpt4 key购买 nike

我问了一个similar questions yesterday关于 postgress,以及它是否可以从 select 语句的结果形状推断出类型。

今天我想从查询返回一个结果集,这是我发现有效的查询:

DROP TYPE IF EXISTS topic_result_entry CASCADE;
CREATE TYPE topic_result_entry AS
(
id INTEGER,
last_post_at TIMESTAMP WITHOUT TIME ZONE,
is_sticky BOOLEAN,
is_poll BOOLEAN,
has_prefix BOOLEAN,
prefix CHARACTER VARYING,
title CHARACTER VARYING,
post_count INTEGER,
started_by INTEGER,
started_at TIMESTAMP WITHOUT TIME ZONE
);

CREATE OR REPLACE FUNCTION get_paginated_topics(
forum_id_ INTEGER, category_id_ INTEGER, page_number_ INTEGER, topics_per_page_ INTEGER)
RETURNS SETOF topic_result_entry as $$
DECLARE
zero_based_index INTEGER;
lower_offset INTEGER;
upper_offset INTEGER;

BEGIN
zero_based_index := page_number_ -1;
lower_offset := zero_based_index * topics_per_page_;
upper_offset := ( (topics_per_page_ * page_number_) + 1 );

RETURN query
select id,last_post_at, is_sticky, is_poll,
has_prefix, prefix, title,post_count,
started_by, started_at
from (
select row_number() OVER(ORDER by last_post_at desc) as rn, *
from forum_topics where category_id = category_id_ and forum_id= forum_id_
) as foo
where rn > lower_offset and rn < upper_offset;
END;
$$ LANGUAGE plpgsql;

结果集的形状可以从select的参数列表+源表的schema定义中推断出来。

Q1。 9.1 中是否有一些语法糖,如果没有,是否在路线图上?

Q2 是否有更简洁的方式来做到这一点?

离题

select id,last_post_at, is_sticky, is_poll, 
has_prefix, prefix, title,post_count,
started_by, started_at
from (
select row_number() OVER(ORDER by last_post_at desc) as rn, *
from forum_topics where category_id = 72
) as foo
where rn>0 and rn<22

QUERY PLAN
Subquery Scan on foo (cost=0.00..492.20 rows=28 width=60)
Filter: ((foo.rn > 0) AND (foo.rn < 22))
-> WindowAgg (cost=0.00..409.42 rows=5519 width=156)
-> Index Scan using forum_topics_last_post_at_idx1 on forum_topics (cost=0.00..326.63 rows=5519 width=156)
Filter: (category_id = 72)

最佳答案

语法糖?我给你买了一些。

如果……

The shape of the resultset can be inferred from [...] the schema definition of the source table

...那么你可以大大简化。在 PostgreSQL 中,表定义会自动定义一个同名的类型。


CREATE OR REPLACE FUNCTION get_paginated_topics(
_forum_id int, _category_id int, _page_number int, _topics_per_page int)
RETURNS <b>SETOF forum_topics</b> AS
$BODY$
DECLARE
_lower_offset int := (_page_number - 1) * _topics_per_page;
_upper_offset int := _topics_per_page * _page_number + 1;
BEGIN

RETURN QUERY
SELECT *
FROM forum_topics f
WHERE f.category_id = category_id_
AND f.forum_id = forum_id_
ORDER BY f.last_post_at DESC
LIMIT _lower_offset
OFFSET _upper_offset;

END;
$BODY$ LANGUAGE plpgsql;

其他细节:

  • 按照@user272735 指出的那样使用 LIMIT/OFFSET。

    • 然后你可以使用 SELECT *,因为你去掉了多余的列。
  • 您可以在声明时分配变量。

  • 短类型名称。

  • 删除了多余的括号。

  • 我在查询中添加了表别名和表限定,这在本例中不是必需的,但这是避免 plpgsql 函数中命名冲突的良好做法。

关于sql - 从 select 语句推断的 Postgres 隐式类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11566895/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com