psql 9.1 ERROR: column must appear in the GROUP BY clause or be used in an aggregate function
psql 9.1 ERROR: column must appear in the GROUP BY clause or be used in an aggregate function
我有 3 个 table:摘要、细分、人员。
people
Column | Type |
------------------+-----------------------------+
id | bigint |
last_name | character varying |
middle_name | character varying |
first_name | character varying |
current_position | character varying |
summaries
Column | Type |
----------------+-----------------------------+
id | bigint |
channel | character varying |
show | character varying |
seg_ids | character varying | segment ids
date | timestamp without time zone |
start_time | timestamp without time zone |
end_time | timestamp without time zone |
segments
Column | Type |
--------------------+-----------------------------+
id | bigint |
block_id | integer |
person_id | bigint | foreign key (FK)
person_role | character varying |
summ | integer | summary id FK
deleted | boolean |
我的 table 摘要有一列 seg_ids(段 ID),它是一个整数字符串,我可以使用此查询将其转换为整数数组 return超过一千个 ID:
select regexp_split_to_array((select rtrim(ltrim(replace((select string_agg(seg_ids, ', ')), '], [', ', '), '['),']') from summaries where date between '2018-07-04' and '2018-07-06'),',')::int[];
现在有了那个整数数组 (seg_ids),我想用它来显示所有摘要和与细分相关的人员。我尝试此查询失败:
SELECT summ, block_id, person, seg.id as segid, su.channel, su.show, date::timestamp::date as shdate, "time"(su.start_time) as shst, CONCAT (ppl.last_name, ', ', ppl.first_name) AS full_name, substr(person_role, 1, 2) as person_role
FROM segments seg
LEFT JOIN summaries su on seg.summ = su.id
LEFT JOIN people ppl on ppl.id = person_id
HAVING seg.id::int = any (
regexp_split_to_array((
SELECT
rtrim(ltrim(
replace(
string_agg(seg_ids, ', ')
, '], [', ', ')
, '['),']')
FROM summaries
WHERE date between '2018-07-04' and '2018-07-06')
,',')::int[]) order by shdate, channel, shst, show, su.id, block_id, person,seg.id asc;
这是给我这个错误:
ERROR: column "seg.summ" must appear in the GROUP BY clause or be used in an aggregate function
我不想按结果分组,因为我会得到比预期少的行。我怎样才能重写查询,这样我就不必按结果分组了?
更新
人在段 table 中。
SELECT summ,
block_id,
person,
seg.id as segid,
su.channel, su.show,
date::TIMESTAMP::date AS shdate,
"time"(su.start_time) AS shst,
"time"(su.end_time) AS shet,
regexp_split_to_array(rtrim(ltrim(su.seg_ids, '['), ']'), ',')::int[] AS seg_id_int_arr,
CONCAT (ppl.last_name, ', ', ppl.first_name) AS full_name,
substr(person_role, 1, 2) AS person_role
FROM summaries su
LEFT JOIN segments seg ON seg.summ = su.id
LEFT JOIN people ppl ON ppl.id = person_id
WHERE date BETWEEN '2018-07-04' AND '2018-07-06'
AND seg.id::int = ANY (regexp_split_to_array(rtrim(ltrim(seg_ids, '['), ']'), ',')::int[])
ORDER BY shdate, channel, shst, show, su.id, block_id, person, seg.id ASC;
你做错了一些基本的事情
- 您应该知道何时使用 having/where 子句。 Where 子句用于在执行聚合之前过滤行(这可以使用 group by 或其他聚合函数)。而 Having 子句用于在执行聚合后过滤数据。可以参考这个explanation
我看到段 table 已经有摘要 ID 和人员 ID,因此您试图在 having 子句中实现的最后一个条件可以通过连接来简化。据我了解,您需要摘要位于特定日期范围内的所有细分信息,这可以通过简单地改进我们的连接条件来完成,例如
FROM segments seg
JOIN summaries su on seg.summ = su.id
AND su.date between '2018-07-04' and '2018-07-0`6'`
LEFT JOIN people ppl on ppl.id = person_id
我还看到你选择了一个名为 person 的列,但我在你的任何 table
中都看不到它
我有 3 个 table:摘要、细分、人员。
people
Column | Type |
------------------+-----------------------------+
id | bigint |
last_name | character varying |
middle_name | character varying |
first_name | character varying |
current_position | character varying |
summaries
Column | Type |
----------------+-----------------------------+
id | bigint |
channel | character varying |
show | character varying |
seg_ids | character varying | segment ids
date | timestamp without time zone |
start_time | timestamp without time zone |
end_time | timestamp without time zone |
segments
Column | Type |
--------------------+-----------------------------+
id | bigint |
block_id | integer |
person_id | bigint | foreign key (FK)
person_role | character varying |
summ | integer | summary id FK
deleted | boolean |
我的 table 摘要有一列 seg_ids(段 ID),它是一个整数字符串,我可以使用此查询将其转换为整数数组 return超过一千个 ID:
select regexp_split_to_array((select rtrim(ltrim(replace((select string_agg(seg_ids, ', ')), '], [', ', '), '['),']') from summaries where date between '2018-07-04' and '2018-07-06'),',')::int[];
现在有了那个整数数组 (seg_ids),我想用它来显示所有摘要和与细分相关的人员。我尝试此查询失败:
SELECT summ, block_id, person, seg.id as segid, su.channel, su.show, date::timestamp::date as shdate, "time"(su.start_time) as shst, CONCAT (ppl.last_name, ', ', ppl.first_name) AS full_name, substr(person_role, 1, 2) as person_role
FROM segments seg
LEFT JOIN summaries su on seg.summ = su.id
LEFT JOIN people ppl on ppl.id = person_id
HAVING seg.id::int = any (
regexp_split_to_array((
SELECT
rtrim(ltrim(
replace(
string_agg(seg_ids, ', ')
, '], [', ', ')
, '['),']')
FROM summaries
WHERE date between '2018-07-04' and '2018-07-06')
,',')::int[]) order by shdate, channel, shst, show, su.id, block_id, person,seg.id asc;
这是给我这个错误:
ERROR: column "seg.summ" must appear in the GROUP BY clause or be used in an aggregate function
我不想按结果分组,因为我会得到比预期少的行。我怎样才能重写查询,这样我就不必按结果分组了?
更新
人在段 table 中。
SELECT summ,
block_id,
person,
seg.id as segid,
su.channel, su.show,
date::TIMESTAMP::date AS shdate,
"time"(su.start_time) AS shst,
"time"(su.end_time) AS shet,
regexp_split_to_array(rtrim(ltrim(su.seg_ids, '['), ']'), ',')::int[] AS seg_id_int_arr,
CONCAT (ppl.last_name, ', ', ppl.first_name) AS full_name,
substr(person_role, 1, 2) AS person_role
FROM summaries su
LEFT JOIN segments seg ON seg.summ = su.id
LEFT JOIN people ppl ON ppl.id = person_id
WHERE date BETWEEN '2018-07-04' AND '2018-07-06'
AND seg.id::int = ANY (regexp_split_to_array(rtrim(ltrim(seg_ids, '['), ']'), ',')::int[])
ORDER BY shdate, channel, shst, show, su.id, block_id, person, seg.id ASC;
你做错了一些基本的事情
- 您应该知道何时使用 having/where 子句。 Where 子句用于在执行聚合之前过滤行(这可以使用 group by 或其他聚合函数)。而 Having 子句用于在执行聚合后过滤数据。可以参考这个explanation
我看到段 table 已经有摘要 ID 和人员 ID,因此您试图在 having 子句中实现的最后一个条件可以通过连接来简化。据我了解,您需要摘要位于特定日期范围内的所有细分信息,这可以通过简单地改进我们的连接条件来完成,例如
FROM segments seg JOIN summaries su on seg.summ = su.id AND su.date between '2018-07-04' and '2018-07-0`6'` LEFT JOIN people ppl on ppl.id = person_id
我还看到你选择了一个名为 person 的列,但我在你的任何 table
中都看不到它