我只想从表中选择另一个子查询结果中包含的标识符,并且只能使用前 2 行。
例如,您可以在 PG 上运行查询:
select a.rid
from(
values (41), (42), (43), (44)
) a(rid)
where a.rid in
(
select b.x
from(
values (43), (44), (42), (41)
) b(x)
order by b.x
fetch first 2 rows only
);
它应该返回
41
42
有用。但是,如果我将以下查询与 CTE 一起使用
select rid
from(
values (41), (42), (43), (44)
) s(rid)
where rid in
(
with recursive messages as (
select
rid as "root_id",
parent.id,
parent.sent_date
from
purchase_message parent
where
parent.id = rid
union
select
rid as "root_id",
child.id,
child.sent_date
from
purchase_message child
join messages on
child.parent_message_id = messages.id
),
ordered_root_ids as (
select
m."root_id",
max(m."sent_date") over (partition by m."root_id") as "maxSentDate"
from
messages m
order by "maxSentDate" desc
)
select "root_id" from ordered_root_ids
fetch first 2 rows only
)
它不起作用。我得到了所有结果
41, 42, 43, 44
为什么它不只返回 2 个结果?按照我的预期肯定只有2个结果,而且一定是43和44,因为它们是最新的消息。
我不知道如何提供所有相关的表,因为太多了。我希望它们没有必要。CTE 或递归 CTE 或嵌套查询是否会影响此?还是所有这些的组合?如何修改上面的查询,以便它对子查询中的数据进行排序,获取顶部的 2 行,然后将它们用于in
外部查询的子句中?
事实并非如此。除了两行之外,没有办法
limit 2
返回更多内容。fetch first 2 rows only
尽管如此,您正在检查的每个值都会获得 2 行,因此这已经足够了。这:将为每个
rid
独立运行带括号的子表达式,就像子查询一样,因为您引用了内部的lateral
外部。rid
因此,对于您检查的每个值,您最多会获得两个匹配项。我猜您预计只会获得 2 个匹配项一次,并且会将in()
每个值与这两个值进行比较。您可以将输入移动到 CTE,然后
rid
从子查询中一次引用其所有 s,让它们全部沿层次结构下降,一起排序,然后一起过滤到顶部 2. db<>fiddle 上的演示:我还必须更改您的逻辑,即根据层次结构中
root_id
最新的内容选择前两个。sent_date
一旦允许对所有输入进行操作rid
,您的代码将继续选择 2 个相同的输入rid
:由于您使用了窗口函数,您将获得每个层次结构的所有行,每个行都重复其
max(sent_date)
. 只要最新的层次结构sent_date
中有 2 行或更多行,您就会得到这两行,因为它们都具有相同的max(sent_date)
和 相同的rid
.您的查询似乎已损坏,我无法在您的版本中执行它看起来像这样
而且效果很好
如果您发布表格数据以了解问题所在,那就更好了