2012-09-21 37 views
0

我目前正在尝试优化使用mysql和openreports进行会计使用的报告。虽然我确信有更好的工具可以完成这些工作,但这些都是我目前需要处理的。我做了以下计算字段:多个嵌套查询

客户端, 订货数量, 客户成本, 客户端的调整, 调整客户的价格(客户成本 - 客户端调整), 供应商成本, 厂商调整, 调整供应商价格(厂商成本 - 供应商调整), 保证金((客户计费 - 供应商结算)/客户收费), ADJ保证金((形容词客户价格形容词供应商价格)/形容词客户端)

的表是相当大我必须为每个内部连接加入4个表格。之前的报告有一个工会,并且在工会的每一边都有大约20个嵌套选择,所有这些选举至少包含四个连接和计数。由于我正在根据以前的字段进行计算,因此每个嵌套select都逐渐变大,包含所有嵌套的选择,计数和来自先前计算的计算。该查询现在是400行,非常昂贵,并且对系统征税,特别是对于大客户。

我意识到这项工作有更好的工具,但我想知道对于这种情况理想的解决方案是什么。我可以在查询中创建一个用户定义的变量并在以后使用它吗?如果我每个客户端有多个查询,这会工作吗?在这篇文章中,我不能包含整个400行的查询,但我可以提供任何其他细节,这些细节可能会有所帮助。任何有识之士将不胜感激。

select office_1.name as 'Client' 
,count(distinct(property_1.id)) as 'Total Billed Orders', 
(select format(coalesce(sum(serviceprice_2.amount),0),2) 
    from cap.service_price serviceprice_2 
    inner join cap.service service_2 on service_2.id = serviceprice_2.service_id 
    inner join cap.service_area servicearea_2 on servicearea_2.id = service_2.service_area_id 
    inner join cap.property property_2 on property_2.id = servicearea_2.property_id 
    inner join cap.office office_2 on office_2.id = property_2.client_id 
    where serviceprice_2.price_context = 'CLIENT' 
    and serviceprice_2.price_type_id = 236 
    && service_2.date_client_billed between '2012-09-01' and now() 
    and service_2.gl_code_ap='4700-70-000' 
    and service_2.date_cancelled is null 
    and office_2.id = office_1.id) as 'Client Price' 
/* other calculations between here */ 
from cap.service service_1 
inner join cap.service_area servicearea_1 on servicearea_1.id = service_1.service_area_id 
inner join cap.property property_1 on property_1.id = servicearea_1.property_id 
inner join cap.office office_1 on office_1.id = property_1.client_id 
inner join cap.office vendor_1 on vendor_1.id = service_1.vendor_id 
where 
service_1.date_client_billed between '2012-09-01' and now() 
and service_1.date_cancelled is null 
and office_1.id = 26377 
and service_1.gl_code_ap='4700-70-000' 
group by office_1.id 
; 

回答

0

使用视图可以简化查询,尽管对性能没有影响。

create view view1 as 
select * 
from 
    cap.service_price serviceprice_2 
    inner join cap.service service_2 on service_2.id = serviceprice_2.service_id 
    inner join cap.service_area servicearea_2 on servicearea_2.id = service_2.service_area_id 
    inner join cap.property property_2 on property_2.id = servicearea_2.property_id 
    inner join cap.office office_2 on office_2.id = property_2.client_id 
; 
create view view2 as 
select * 
from 
    cap.service service_1 
    inner join cap.service_area servicearea_1 on servicearea_1.id = service_1.service_area_id 
    inner join cap.property property_1 on property_1.id = servicearea_1.property_id 
    inner join cap.office office_1 on office_1.id = property_1.client_id 
    inner join cap.office vendor_1 on vendor_1.id = service_1.vendor_id 

现在查询是更易于管理:

select @client_price := format(coalesce(sum(serviceprice_2.amount),0),2) 
from view1 
where serviceprice_2.price_context = 'CLIENT' 
    and serviceprice_2.price_type_id = 236 
    && service_2.date_client_billed between '2012-09-01' and now() 
    and service_2.gl_code_ap='4700-70-000' 
    and service_2.date_cancelled is null 
    and office_2.id = office_1.id 
; 
select 
    office_1.name as 'Client' 
    ,count(distinct(property_1.id)) as 'Total Billed Orders', 
    @client_price 
/* other calculations between here */ 
from view2 
where 
    service_1.date_client_billed between '2012-09-01' and now() 
    and service_1.date_cancelled is null 
    and office_1.id = 26377 
    and service_1.gl_code_ap='4700-70-000' 
group by office_1.id 
+0

我认为对业绩的影响主要是我在整个脚本,但略有不同的过滤器中加入如此多的子查询相同的表的事实。此外,我一遍又一遍地执行相同的查询,以继续获得计算,这就是为什么我想知道用户定义的变量是否会在这种情况下有用,尽管我对他们是陌生的,并没有看到使用它们的例子我描述的方式。这一切都必须在一个自包含的脚本中运行。做一个视图或者添加一个表来存储这些值的月间隔可能是答案 – user1521319

+0

你的例子看起来更容易维护,所以我可能会研究这个问题。即使表现不会受到影响,它也可以帮助我保持清醒。 – user1521319

+0

@ user1521319是的,您可以将结果存储在变量中并稍后使用。我编辑了我的例子。 'select @sum_service:=' –