PostgreSQL条件语句

3
我需要根据另一个语句的结果实现一个有条件的SELECT语句。我不想为此创建一个函数,而是仅使用有条件的SELECT语句。
我的失败尝试如下所示:
DO
$do$
BEGIN
IF SELECT count(*) FROM table1 < 1 THEN
   SELECT * FROM table2;
   RETURN QUERY;

ELSE 
   SELECT * FROM table3;
   RETURN QUERY;
END IF;
END
$do$

我可以通过在PHP中检查我的查询结果并根据此执行另一个查询来实现相同的结果,但我想知道是否可能仅在PostgreSQL中完成此操作。


@NickBarnes 我编辑了这篇文章:第一个查询必须计算结果,然后基于此另一个查询必须返回结果。在我的特定情况下,所有查询都相当长,所以我决定用更简单的等效替换它们。如果你问列,所有三个查询将有相同的列。 - jacek_podwysocki
return query 是一个单独的语句。它应该是 return query select ... - 但是 PL/pgSQL 块不能返回任何东西,所以你无法在其中使用 return query - user330315
@a_horse_with_no_name 说得好,有没有可能让 PL/pgSQL 返回一个查询? - jacek_podwysocki
1
你可以让一个 PL/PgSQL 函数返回一些内容,但匿名块不行。 - user330315
2个回答

2

试试这个:

with c as (select count(*) cnt from table1)
select table2.* from table2, c where c.cnt < 1
union all
select table3.* from table3, c where c.cnt >= 1

3
一般情况下,如果您想知道查询是否不存在,使用 NOT EXISTS 要比 COUNT(*) < 1 更好。 - acesargl
是的。如果条件只涉及存在(如问题所述),那么“EXISTS”肯定更可取。 - Gregor Raýman
@acesargl 使用 with 是首选,当您想要多次使用 SELECT 时,您也可以在您的答案中使用 with - shA.t
使用count函数可以强制计算所有元组,使用NOT EXISTS当找到一个元组时,内部SELECT会被中止(EXISTS和NOT EXISTS通常使用短路或麦卡锡评估)。 - acesargl

2

如果table2和table3兼容,则可以使用单个SELECT:

SELECT * FROM table2 WHERE NOT EXISTS(SELECT * FROM table1)
UNION
SELECT * FROM table3 WHERE EXISTS(SELECT * FROM table1);

3
性能问题时,请使用 UNION ALL 而不是 UNION ;)。 - shA.t
我还建议您使用SELECT 1 FROM table1而不是SELECT * FROM table1 ;)。 - shA.t
存在和不存在在嵌套查询中忽略投影列表。因此,在这种情况下,select * 和 select 1 是等价的。 - acesargl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接