【发布时间】:2014-10-13 01:58:20
【问题描述】:
我有一个表格,用于存储帐户随时间的变化。如果这些记录尚不存在,我需要将其与其他两个表连接起来以创建特定日期的一些记录。
为了让事情变得更简单(我希望如此),我将返回正确历史数据的查询封装到一个函数中,该函数接受帐户 ID 和日期。
如果我执行"Select * account_servicetier_for_day(20424, '2014-08-12')",我会得到预期的结果(从函数返回的所有数据在单独的列中)。如果我在另一个查询中使用该函数,我会将所有列合并为一个:
("2014-08-12 14:20:37",hollenbeck,691,12129,20424,69.95,"2Mb/1Mb 20GB Limit",2048,1024,20.000)
我正在使用“x86_64-slackware-linux-gnu 上的 PostgreSQL 9.2.4,由 gcc (GCC) 4.7.1 编译,64 位”。
查询:
Select
'2014-08-12' As day, 0 As inbytes, 0 As outbytes, acct.username, acct.accountid, acct.userid,
account_servicetier_for_day(acct.accountid, '2014-08-12')
From account_tab acct
Where acct.isdsl = 1
And acct.dslservicetypeid Is Not Null
And acct.accountid Not In (Select accountid From dailyaccounting_tab Where Day = '2014-08-12')
Order By acct.username
功能:
CREATE OR REPLACE FUNCTION account_servicetier_for_day(_accountid integer, _day timestamp without time zone) RETURNS setof account_dsl_history_info AS
$BODY$
DECLARE _accountingrow record;
BEGIN
Return Query
Select * From account_dsl_history_info
Where accountid = _accountid And timestamp <= _day + interval '1 day - 1 millisecond'
Order By timestamp Desc
Limit 1;
END;
$BODY$ LANGUAGE plpgsql;
【问题讨论】:
-
当您在标量上下文中选择一条记录时,它会被转换为一个字符串。您可能需要从子查询中的函数中进行选择并将其连接到
account_tab。 -
@cdhowie 它没有转换为字符串。它仍然是函数返回的复合类型
account_dsl_history_info。 -
@ClodoaldoNeto 公平点。我怀疑当他在他选择的编程环境中检索这个值时,它不会理解如何将它表示为除字符串之外的任何东西。 (有些驱动程序可以处理创纪录的值,有些则不能。)
-
很遗憾,Postgres 9.3 会提供方便的
JOIN LATERAL。 -
我应该接受哪个答案? @ClodoaldoNeto 首先根据我最初说明(错误地)我使用的是 Postgresql 9.3 的问题正确回答。但 ErwinBrandstetter 给出了更完整的答案,发布了有关 v9.2 的信息。
标签: sql postgresql join plpgsql set-returning-functions