1

我的代码看起来像这样(模式),因为它非常庞大:

something AS ( SELECT DISTINCT ON (x1,x2,x3,x4) ... ),
something2 AS (xx.*, ... FROM something xx LEFT JOIN ...),
something3 AS (xx.*, ... FROM something2 xx LEFT JOIN ...)
SELECT ... FROM something3

所以想象一下这种情况:在使用DISTINCT ON (x1,x2,x3,x4something )之后

select * from something

(忽略something2 and something3这里):我得到 1700 个结果。

问题是这不是我的预期结果(还),因为我需要使用更多的 CTE 来 leftjoin 一些信息

所以当我有相同的DISTINCT ONsomething并且我做

select * from something3(这是应返回 1700 行的最终预期结果)

我突然得到了 4000 个结果,其中包含我之前想要区分的值something

好像我丢失了DISTINCTIve type in something,因为当我输入相同的语法时:

DISTINCT ON (x1,x2,x3,x4) ...在所有三个中something's,我得到 1700 个结果 - 但这并不是我真正想要的。

时间对我来说很重要。

有人可以帮助我解决问题并更好地理解这里的问题吗?

4

1 回答 1

1

发生这种情况,因为

CTE 可以被认为是定义了只为一个查询而存在的临时表。

这意味着,如果您使用子句定义了一个 CTE,这并不重要,DISTINT ON因为其他 CTE(和您的主查询)只会看到一个临时表(或者更像是一个结果集),但仅此而已。如果在这个临时表上使用连接,你可能会得到更多的结果(就像普通表一样)。

为确保您的主查询不包含重复项,请将DISTINT ON子句移到那里(或者,理论上,您的所有 CTE 都可以拥有它 - 但至少最后一个应该拥有)。

前任 这些应该产生您想要的输出:

WITH s AS (SELECT x FROM t),
s2 AS (SELECT x FROM s),
s3 AS (SELECT x FROM s2),
SELECT DISTINCT x FROM s3;

-- vs.

WITH s AS (SELECT x FROM t),
s2 AS (SELECT x FROM s),
s3 AS (SELECT DISTINCT x FROM s2),
SELECT x FROM s3;

-- vs.

WITH s AS (SELECT DISTINCT x FROM t),
s2 AS (SELECT DISTINCT x FROM s),
s3 AS (SELECT DISTINCT x FROM s2),
SELECT x FROM s3;

-- this last version should be only used, when you have
-- enormous joins, so you want to keep your "temporary"
-- tables' size smaller in the memory
于 2014-06-27T14:40:07.987 回答