【问题标题】:Return first available row if initial SELECT finds nothing, in a single statement如果初始 SELECT 没有找到任何内容,则在单个语句中返回第一个可用行
【发布时间】:2021-09-26 17:02:33
【问题描述】:

我正在尝试组合一个 SQL 查询,该查询将基于简单的WHERE 条件返回数据,但如果条件不满足,也会返回第一个可用记录。

author_id post_id publish_date
1 31 2021-07-23
2 432 2021-06-22
2 555 2020-07-23

使用我的基本查询上面的数据看起来像这样

select *
from posts
where author_id = 1
and publish_date > '2021-07-01'
order by publish_date

结果,即作者在指定日期后发表的帖子

author_id post_id publish_date
1 31 2021-07-23

由于作者 2 在此日期之后没有帖子,我希望它返回指定作者的最新帖子。 我希望能够输出“作者>自search_date>以来没有发布,最近的帖子是在publish_date> " 无需多次查询数据库。

author_id 2 的期望结果(没有任何发布日期 > '2021-07-01' 的帖子)

author_id post_id publish_date
2 432 2021-06-22

如果单条语句不满足日期条件,是否可以查询第一条可用记录?

【问题讨论】:

  • 您需要将这两条记录作为两行(具有相同的列)吗?

标签: sql postgresql


【解决方案1】:

可以通过单个查询:

WITH cte AS (
   SELECT *
   FROM   posts
   WHERE  author_id = 1
   AND    publish_date > '2021-07-01'
   ORDER  BY publish_date
   )
TABLE cte
UNION ALL
(  -- parentheses required
SELECT *
FROM   posts
WHERE  NOT EXISTS (SELECT FROM cte)
AND    author_id = 1
AND    publish_date <= '2021-07-01'
ORDER  BY publish_date DESC NULLS LAST
LIMIT  1
);

相关:

或者使用 PL/pgSQL 函数:

CREATE OR REPLACE FUNCTION my_func(_author_id int, _publish_date date)
  RETURNS SETOF posts
  LANGUAGE plpgsql aS
$$
BEGIN
   RETURN QUERY
   SELECT *
   FROM   posts
   WHERE  author_id = _author_id
   AND    publish_date > _publish_date
   ORDER  BY publish_date;
   
   IF NOT FOUND THEN
      RETURN QUERY
      SELECT *
      FROM   posts
      WHERE  author_id = _author_id
      AND    publish_date <= _publish_date
      ORDER  BY publish_date DESC NULLS LAST
      LIMIT  1;
   END IF;
END
$func$;

呼叫:

SELECT * FROM my_func(2,'2021-07-01');

相关:

【讨论】:

    【解决方案2】:

    您可以为此创建一个函数并获得您想要的实现条件:

    create or replace function some_func(input_author_id integer, input_date date)
        returns setof posts
    as
    $$
    declare
        selected_posts posts%rowtype;
    begin
        select * from posts p into selected_posts where p.author_id = input_author_id and p.publish_date > input_date;
        if not found then
            return query
            select * from posts p where p.author_id = input_author_id order by publish_date desc limit 1;
        else 
            return query
            select * from posts p where p.author_id = input_author_id and p.publish_date > input_date;
        end if;
    end
    $$
    language plpgsql;
    

    之后,只需传递你想要的参数值:

    select * from some_func(2,'2021-07-01');
    

    这将为您提供以下结果:

    author_id post_id publish_date
    2 432 2021-06-22

    【讨论】:

      猜你喜欢
      • 2021-11-19
      • 1970-01-01
      • 2021-02-05
      • 2016-04-20
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多