英文:
Postgres variables in select and error when using repeat
问题
以下是您提供的代码部分的中文翻译:
假设以下情况,
创建表 person(id 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 > 0 and rating <= 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('★', ceil(avg(rating)::numeric(10, 2))),
repeat('☆', 5 - ceil(avg(rating)::numeric(10, 2)))
) as rating_as_stars
from person_rating;
I'm expecting the following result:
{
"rating_averaged": 3.25,
"rating_rounded_up": 4,
"rating_as_stars": "★★★★☆"
}
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('hello! ', 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?
答案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('★', rating_rounded_up )
, repeat('☆', 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('★', ceil(avg(rating)::numeric(10, 2))::integer),
repeat('☆', 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
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论