【发布时间】: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