gpt4 book ai didi

sql - postgresql函数混淆

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

如果我这样写一个查询:

with WordBreakDown (idx, word, wordlength) as (
select
row_number() over () as idx,
word,
character_length(word) as wordlength
from
unnest(string_to_array('yo momma so fat', ' ')) as word
)
select
cast(wbd.idx + (
select SUM(wbd2.wordlength)
from WordBreakDown wbd2
where wbd2.idx <= wbd.idx
) - wbd.wordlength as integer) as position,
cast(wbd.word as character varying(512)) as part
from
WordBreakDown wbd;

...我得到一个 4 行的表格,如下所示:

1;"yo"
4;"momma"
10;"so"
13;"fat"

...这就是我想要的。 但是,如果我将其包装成这样的函数:

drop type if exists split_result cascade;
create type split_result as(
position integer,
part character varying(512)
);

drop function if exists split(character varying(512), character(1));
create function split(
_s character varying(512),
_sep character(1)
) returns setof split_result as $$
begin

return query
with WordBreakDown (idx, word, wordlength) as (
select
row_number() over () as idx,
word,
character_length(word) as wordlength
from
unnest(string_to_array(_s, _sep)) as word
)
select
cast(wbd.idx + (
select SUM(wbd2.wordlength)
from WordBreakDown wbd2
where wbd2.idx <= wbd.idx
) - wbd.wordlength as integer) as position,
cast(wbd.word as character varying(512)) as part
from
WordBreakDown wbd;

end;
$$ language plpgsql;

select * from split('yo momma so fat', ' ');

...我得到:

1;"yo momma so fat"

我正在为这个问题挠头。我搞砸了什么?

更新根据以下建议,我已经替换了函数:

CREATE OR REPLACE FUNCTION split(_string character varying(512), _sep character(1))
RETURNS TABLE (postition int, part character varying(512)) AS
$BODY$
BEGIN
RETURN QUERY
WITH wbd AS (
SELECT (row_number() OVER ())::int AS idx
,word
,length(word) AS wordlength
FROM unnest(string_to_array(_string, rpad(_sep, 1))) AS word
)
SELECT (sum(wordlength) OVER (ORDER BY idx))::int + idx - wordlength
,word::character varying(512) -- AS part
FROM wbd;
END;
$BODY$ LANGUAGE plpgsql;

...它保留了我的原始函数签名以获得最大的兼容性,并获得了大部分的性能提升。感谢回答者,我发现这是一次多方面的学习经历。您的解释确实帮助我理解了发生的事情。

最佳答案

注意这个:

select length(' '::character(1));
length
--------
0
(1 row)

造成这种混淆的一个原因是 SQL 标准中对 character 类型的奇怪定义。来自 Postgres documentation for character types :

字符类型的值在物理上用空格填充到指定宽度 n,并以这种方式存储和显示。但是,填充空间在语义上被视为无关紧要。 尾随空格在比较两个字符类型的值时被忽略,并且它们在将字符值转换为其他字符串类型之一时将被删除

所以你应该使用string_to_array(_s, rpad(_sep,1))

关于sql - postgresql函数混淆,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9690960/

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