我有property
,每个property
都有contracts
,每个contract
都有整数字段rental_area
。
以前我必须得到财产总结的所有合同的rental_area
,这是有效的。
SELECT
Sum(cr.rental_area) total_property_rental_area,
-- bunch of other cr fields
FROM appdata.contract_rental cr
INNER JOIN appdata.domain_building b1
ON ( b1.building_id = cr.building_id )
INNER JOIN appdata.domain_immovable im1
ON ( im1.immovable_id = b1.immovable_id )
GROUP BY im1.property_id
现在逻辑已更改,并且合约有一个periods
列表,其中一个句点包含该合约的rental_area
。找到正确的period
需要一些特殊的逻辑。
我试图将逻辑加入到查询中,但找不到一个地方,在哪里放置它所以我必须创建存储过程。
SELECT Sum(p.rental_area) total_property_rental_area
-- bunch of other cr fields
FROM appdata.contract_rental cr
JOIN appdata.rental_period p
ON p.id = Get_current_period_id(cr.contract_rental_id,
cr.end_date_actual)
INNER JOIN appdata.domain_building b1
ON ( b1.building_id = cr.building_id )
INNER JOIN appdata.domain_immovable im1
ON ( im1.immovable_id = b1.immovable_id )
GROUP BY im1.property_id
步骤:
CREATE OR REPLACE FUNCTION appdata.get_current_period_id(in contract_id_in bigint, in end_date_actual_in Date)
RETURNS bigint AS
$BODY$
DECLARE
period_id bigint;
BEGIN
-- find the period that matches with end date or current date
select id into period_id
from rental_period
where contract_id = contract_id_in
and Coalesce(end_date_actual_in, Now()) >= start_date
order by start_date desc limit 1;
-- if there was no period, just take the first one
IF period_id is null THEN
select id into period_id
from rental_period
where contract_id = contract_id_in
order by start_date asc
limit 1;
END IF;
return period_id;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
但现在它太慢了,是否有办法将周期查找逻辑放入sql中以使其更快,而不使用存储过程? 重点是,对于达成合同,它必须只根据逻辑获得单个期间。
答案 0 :(得分:1)
将存储过程转出回主SQL,主要提示正在合并你的2个查询(如果一个为null则使用另一个)
示例:而不是
p.id = Get_current_period_id(cr.contract_rental_id,
cr.end_date_actual)
使用:
p.pid = coalesce(
(select rpx.id
from rental_period rpx
where contract_id = cr.contract_rental_id
and Coalesce(cr.end_date, Now()) >= start_date
order by start_date desc limit 1;
),
( select rpy.id
from rental_period rpy
where contract_id = cr.contract_rental_id
order by start_date asc
limit 1;
)
)
根据以下评论,以下索引也可能有所帮助:
create index on rental_period (contract_id, start_date asc)
请务必在之后分析表格以更新统计数据。