【问题标题】:why does this function not return the excpected tsrange[]为什么这个函数不返回预期的 tsrange[]
【发布时间】:2021-08-24 09:49:53
【问题描述】:

我有这些表和这个数据集

CREATE TABLE  employee (entity_id uuid, valid tsrange);
INSERT into employee (entity_id, valid)
VALUES
('0006f79d-5af7-4b29-a200-6aef3bb0105f', tsrange('2009-05-23 02:00:00','2010-08-27 02:00:00')),
('0006f79d-5af7-4b29-a200-6aef3bb0105f', tsrange('2010-08-27 02:00:00','2010-10-27 02:00:00')),
('0006f79d-5af7-4b29-a200-6aef3bb0105f', tsrange('2011-05-23 02:00:00','infinity'))

我想选择一个每个连续聚合的tsrange,作为一个tsrange[],作为一个特定的entity_id

为此我有这个功能

CREATE OR REPLACE FUNCTION tsrange_cluster_aggregate(_tbl regclass, selected_entity_id uuid)
  RETURNS SETOF TSRANGE AS
$$
BEGIN
EXECUTE
FORMAT(
 'SELECT tsrange(min(COALESCE(lower(valid), ''-infinity'')), max(COALESCE(upper(valid), ''infinity'')))
FROM  (
   SELECT *, count(nextstart > enddate OR NULL) OVER (ORDER BY valid DESC NULLS LAST) AS grp
   FROM  (
      SELECT valid
           , max(COALESCE(upper(valid), ''infinity'')) OVER (ORDER BY valid) AS enddate
           , lead(lower(valid)) OVER (ORDER BY valid) As nextstart
      FROM %1$I
      where entity_id = %2$L
      ) a
   ) b
GROUP  BY grp
ORDER  BY 1;'
, _tbl , selected_entity_id)
USING _tbl, selected_entity_id;
END
$$ LANGUAGE plpgsql;


SELECT tsrange_cluster_aggregate('employee'::regclass, '0006f79d-5af7-4b29-a200-6aef3bb0105f');

这里的问题是这个函数的输出总是空的?

当我在函数之外运行它时,我得到了预期的输出?

https://dbfiddle.uk/?rdbms=postgres_12&fiddle=a09f8033091ea56e533880feebd0d5d4

【问题讨论】:

    标签: sql postgresql function plpgsql


    【解决方案1】:

    您的函数中缺少RETURN

    CREATE OR REPLACE FUNCTION tsrange_cluster_aggregate(_tbl regclass, selected_entity_id uuid)
      RETURNS SETOF tsrange[] AS
    $$
    BEGIN
    RETURN QUERY EXECUTE
    FORMAT(
     ' SELECT array_agg(j) FROM (
    SELECT tsrange(min(COALESCE(lower(valid), ''-infinity'')), max(COALESCE(upper(valid), ''infinity'')))
    FROM  (
       SELECT *, count(nextstart > enddate OR NULL) OVER (ORDER BY valid DESC NULLS LAST) AS grp
       FROM  (
          SELECT valid
               , max(COALESCE(upper(valid), ''infinity'')) OVER (ORDER BY valid) AS enddate
               , lead(lower(valid)) OVER (ORDER BY valid) As nextstart
          FROM %1$I
          where entity_id = %2$L
          ) a
       ) b
    GROUP  BY grp
    ORDER  BY 1) z (j);'
    , _tbl , selected_entity_id)
    USING _tbl, selected_entity_id;
    END
    $$ LANGUAGE plpgsql;
    

    演示:db<>fiddle

    【讨论】:

    • 如何更改它以返回tsrange[],添加array_agg 类似是因为查询似乎不起作用?
    • 是的,但只要让函数返回tsrange[]
    猜你喜欢
    • 1970-01-01
    • 2017-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-21
    • 2018-01-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多