Postgres中的select变量和在使用repeat时出现的错误

huangapple go评论55阅读模式
英文:

Postgres variables in select and error when using repeat

问题

以下是您提供的代码部分的中文翻译:

假设以下情况,

创建表 personid serial primary key;
创建表 person_rating (
  id serial primary key,
  person_id bigint references person,
  rating smallint constraint rating_person_rating_check check (rating > 0 and rating <= 5)
);

插入到 person 中的值为(1;
插入到 person_rating 中的值为
  (1, 1, 5),
  (2, 1, 2),
  (3, 1, 5),
  (4, 1, 1);

我尝试运行以下查询:

选择
	round(avg(rating)::numeric(10, 2), 2) as rating_averaged,
	ceil(avg(rating)::numeric(10, 2)) as rating_rounded_up,
	concat(
      repeat('★', ceil(avg(rating)::numeric(10, 2))),
      repeat('☆', 5 - ceil(avg(rating)::numeric(10, 2)))
    ) as rating_as_stars
 person_rating;

我期望的结果是:

{
    "rating_averaged": 3.25,
    "rating_rounded_up": 4,
    "rating_as_stars": "★★★★☆"
}

我遇到了以下错误:

查询错误:错误:函数 repeat(unknown, numeric) 不存在

奇怪的是,基本的 repeat 选择工作,例如:

选择 repeat('hello! ', 2);

我还尝试将其强制转换为 ::text::varchar,但错误仍然存在。

我还有一个顾虑,就是重复。例如,在这种情况下,以下序列重复了4次:

avg(rating)::numeric(10, 2)

我该如何解决这个问题?

英文:

Suppose the following,

create table person (id serial primary key);
create table person_rating (
  id serial primary key,
  person_id bigint references person,
  rating smallint constraint rating_person_rating_check check (rating &gt; 0 and rating &lt;= 5)
);

insert into person values (1);
insert into person_rating values
  (1, 1, 5),
  (2, 1, 2),
  (3, 1, 5),
  (4, 1, 1);

I'm trying to run the following query:

select
	round(avg(rating)::numeric(10, 2), 2) as rating_averaged,
	ceil(avg(rating)::numeric(10, 2)) as rating_rounded_up,
	concat(
      repeat(&#39;★&#39;, ceil(avg(rating)::numeric(10, 2))),
      repeat(&#39;☆&#39;, 5 - ceil(avg(rating)::numeric(10, 2)))
    ) as rating_as_stars
from person_rating;

I'm expecting the following result:

{
    &quot;rating_averaged&quot;: 3.25,
    &quot;rating_rounded_up&quot;: 4,
    &quot;rating_as_stars&quot;: &quot;★★★★☆&quot;
}

I'm running into the following error:

Query Error: error: function repeat(unknown, numeric) does not exist

What's weird is that basic repeat selects work, such as:

select repeat(&#39;hello! &#39;, 2);

I've also tried casting as ::text or ::varchar, but the error persists.

Another concern that I have is the repetition. For instance, in this case, the following sequence is repeated 4 times:

avg(rating)::numeric(10, 2)

How can I get around this?

Fiddle

答案1

得分: 1

函数avg(任何整数类型)始终返回一个数值,因此无需重复转换其结果(::numeric(10,2))。此外,正如其他人所指出的,repeat()函数要求第二个参数必须是整数,这将需要进行转换。除此之外,对rating的处理可以限制在公共表达式中,减少了repeat()函数的复杂性和冗长。总体而言,查询可以简化为:(请参见demo)

with ratings(rating_averaged, rating_rounded_up) as 
     ( select round(avg(rating), 2) 
            , ceil(round(avg(rating),2))::integer  
         from person_rating
     )  --select * from ratings;
select rating_averaged 
     , rating_rounded_up 
     , concat( repeat('★', rating_rounded_up )
             , repeat('☆', 5 - rating_rounded_up)
             ) as rating_as_stars 
from ratings;
英文:

The avg(any integer type) function always returns a numeric therefore the repetition of casting its results (::numeric(10,2)) is unnecessary. Also, as others have indicated the repeat() function requires the second parameter to be an integer, which will need a cast. Beyond that the manipulation of rating can be confined to a CTE, reducing the complexity/wordiness of the repeat() functions. Overall the query reduces to: (see demo)

with ratings(rating_averaged, rating_rounded_up) as 
     ( select round(avg(rating), 2) 
            , ceil(round(avg(rating),2))::integer  
         from person_rating
     )  --select * from ratings;
select rating_averaged 
     , rating_rounded_up 
     , concat( repeat(&#39;★&#39;, rating_rounded_up )
             , repeat(&#39;☆&#39;, 5 - rating_rounded_up)
             ) as rating_as_stars 
from ratings; 

答案2

得分: 0

第二个参数必须是整数:

select
    round(avg(rating)::numeric(10, 2), 2) as rating_averaged,
    ceil(avg(rating)::numeric(10, 2)) as rating_rounded_up,
    concat(
      repeat('★', ceil(avg(rating)::numeric(10, 2))::integer),
      repeat('☆', 5 - ceil(avg(rating)::numeric(10, 2))::integer)
    ) as rating_as_stars
from person_rating;

另外,如果您希望保持代码整洁,我建议创建一个基于"rating"参数返回评分的函数。

英文:

The second parameter must be integer:

select
    round(avg(rating)::numeric(10, 2), 2) as rating_averaged,
    ceil(avg(rating)::numeric(10, 2)) as rating_rounded_up,
    concat(
      repeat(&#39;★&#39;, ceil(avg(rating)::numeric(10, 2))::integer),
      repeat(&#39;☆&#39;, 5 - ceil(avg(rating)::numeric(10, 2))::integer)
    ) as rating_as_stars
from person_rating;

Additionally, if you want to keep the code clean, I would suggest create a function that returns a rating based on a "rating" parameter.

答案3

得分: -1

也将repeat的第二个参数转换为integer

英文:

Also cast the second parameter of repeat to integer.

huangapple
  • 本文由 发表于 2023年2月27日 06:47:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/75575456.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定