【问题标题】:Looping through rows inside function循环遍历函数内部的行
【发布时间】:2015-07-03 07:04:35
【问题描述】:

有人可以帮忙处理一个 SQL 函数吗?我需要有一个函数可以循环并在每个循环中执行具有不同日期的查询。如果不为空,我想检查该字段,然后返回该字段或行,如果为空,我想以不同的方式继续循环。

这是我想要的一个例子:

create or replace function getCounterValue(id integer, datee text) RETURNS varchar(20) AS $$
DECLARE
  cvalue varchar(20);

BEGIN
  for x IN 1..365 LOOP
    select cr.counter_value into cvalue
    from snmp_printer p 
      left join snmp_counters_scan cs on(p.id=cs.printer)
      left join snmp_printer_model pm on(p.model=pm.id)
      left join snmp_counter c on (pm.id=c.model)
      left join snmp_counters_result cr
        on (cr.snmp_counter=c.id and cr.counters_scan=cs.id)
    where p.id = id
      and c.name='PAGE COUNT'
      and cs.id in (select max(pp.id) from snmp_counters_scan pp
                    where pp.scan_date <= cast(datee as date) -interval x ||'day'
                    group by printer);

    if cvalue is not null then 
        return cvalue;  
    else 
    --continue
    end if;
  END LOOP;
  RETURN cvalue;
END;
$$ LANGUAGE plpgsql;

【问题讨论】:

  • 将 c 条件从 WHERE 移动到 c 的 ON 以获得真正的左连接行为。 (现在左连接作为常规内连接执行......)
  • 您真正需要的是greatest-n-per-group(这里,n 是一个)来获得“最早”的snmp_counters_scan 行。为了获得最佳结果,您可能希望将其作为 CTE 或子查询(因此您不会对整个数据集进行分区)。但是,not-LEFT JOINs 令人困惑(我不知道实际上应该将什么变成常规连接,而不是像@jarlh 所说的那样实际上 被转换)。如果你在 SQL 中循环,通常你做错了什么。

标签: sql database postgresql-9.1


【解决方案1】:

使用滚动光标或使用APPLY 运算符。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-30
    • 2019-12-10
    • 2021-05-21
    • 2020-08-20
    • 1970-01-01
    • 2017-05-12
    • 1970-01-01
    • 2016-08-11
    相关资源
    最近更新 更多