1

我有一张桌子Design和一张名为ArchivedDesign. 视图声明为:

CREATE OR REPLACE VIEW public."ArchivedDesign" ("RootId",  "Id", "Created", "CreatedBy", "Modified", "ModifiedBy", "VersionStatusId", "OrganizationId")
AS
SELECT DISTINCT ON (des."RootId") "RootId", des."Id", des."Created", des."CreatedBy", des."Modified", des."ModifiedBy", des."VersionStatusId", des."OrganizationId"
FROM public."Design" AS des
JOIN public."VersionStatus" AS vt ON des."VersionStatusId" = vt."Id"
WHERE vt."Code" = 'Archived'
ORDER BY "RootId", des."Modified" DESC;

然后,我有一个大型查询,其中包含最新更改、缩略图等的简短摘要。整个查询并不重要,但它包含两个几乎相同的子查询——一个用于主表,一个用于视图。

SELECT DISTINCT ON (1) x."Id",
                TRIM(con."Name") AS "Contributor",
                extract(epoch from x."Modified") * 1000 AS "Modified",
                x."VersionStatusId",
                x."OrganizationId"
FROM public."Design" AS x
JOIN "Contributor" AS con ON con."DesignId" = x."Id"
WHERE x."OrganizationId" = ANY (ARRAY[]::uuid[])
AND x."VersionStatusId" = ANY (ARRAY[]::uuid[])
GROUP BY x."Id", con."Name"
ORDER BY x."Id";

SELECT DISTINCT ON (1) x."Id",
                TRIM(con."Name") AS "Contributor",
                extract(epoch from x."Modified") * 1000 AS "Modified",
                x."VersionStatusId",
                x."OrganizationId"
FROM public."ArchivedDesign" AS x
JOIN "Contributor" AS con ON con."DesignId" = x."Id"
WHERE x."OrganizationId" = ANY (ARRAY[]::uuid[])
AND x."VersionStatusId" = ANY (ARRAY[]::uuid[])
GROUP BY x."Id", con."Name"
ORDER BY x."Id";

链接到 SQL 小提琴:http ://sqlfiddle.com/#!17/d1d0f/1

查询对表有效,但对视图失败并出现错误column x."Modified" must appear in the GROUP BY clause or be used in an aggregate function。我不明白为什么这两个查询的行为有所不同?如何修复视图查询以与表查询相同的方式工作?

我的最终目标是用视图子查询替换所有表子查询,以便我们可以轻松地将草稿、活动和存档设计分开。

4

1 回答 1

2

您会收到该错误,因为当您直接查询表时,Postgres 能够识别表的主键并且知道按它进行分组就足够了。

从手册中引用

当存在 GROUP BY 或存在任何聚合函数时,SELECT 列表表达式引用未分组列是无效的,除非在聚合函数内或当未分组列在功能上依赖于分组列时,否则会有更多为未分组的列返回一个可能的值。如果分组列(或其子集)是包含未分组列的表的主键,则存在函数依赖关系

(强调我的)

查询视图时,Postgres 无法检测到在直接查询表时可以有“缩短”的 GROUP BY 的功能依赖关系。

于 2020-06-03T09:03:16.633 回答