Я не очень хорош в SQL, поэтому я пытался справиться с этим с помощью PHP и выполнять очень простые запросы к MySQL, но, очевидно, у меня не хватает памяти (в PHP), так как я много работаю данных (и делает тонны ужасных вложенных foreach's). Я надеюсь, что может быть способ переписать мой SQL, чтобы этого не произошло.
Вот таблицы, с которыми я имею дело (показаны только соответствующие поля):
Организации
FundingCycles
- CycleID
- NonUnityCutBackAmount
- UnityCutBackAmount
AdministrativeRequests
- CycleID
- OrgID
- AmountRequested
- AmountFunded
- Peroff
CapitalRequests
- CycleID
- OrgID
- AmountRequested
- AmountFunded
- Peroff
EventRequests
- CycleID
- OrgID
- AmountRequested
- AmountFunded
- Peroff
- UnityReq
Итак, вот сложная часть. Мне нужно создать суммы для каждой организации AmountRequested
, AmountFunded
, (эти два кажутся довольно простыми, хотя не уверены в суммировании по нескольким таблицам) и вычисляемое поле AmountAfterCutback
из запросов, которые есть во всех таблицах запросов (AdministrativeRequests
, CapitalRequests
, EventRequests
).
AmountAfterCutback
невероятно похож на: AmountFunded - (AmountFunded * Cutback
).
Это может быть достаточно просто, если сокращение было только одним значением. Тем не менее, Cutback
происходит из таблицы FundingCycles
. Так что я не могу просто суммировать и применить сокращение, я должен найти сокращение для каждого запроса, и для этого мне нужно просмотреть каждый запрос, а затем проверить его CycleID
и посмотреть, для чего сокращение этот запрос находится в таблице FundingCycles
.
По умолчанию Cutback
будет равно NonUnityCutBack
. Однако, если запрос является запросом Unity
(только EventRequests
, UnityReq == 1
), сокращение будет равно UnityCutBack
. Однако это еще более усложняется тем, что сокращение может применяться индивидуально к каждому запросу, переопределяя сокращения единства или неединичности (если PerOff is > 0
).
Итак, каким-то образом я должен суммировать каждый запрос, сделанный организацией, и правильно вычислять поля, упомянутые выше. Ниже я покажу свое решение, которое, как я предупреждаю, определенно не изящное, и на данный момент оно даже не работает, так как ему не хватает памяти при попытке обработать его с помощью PHP. Я знаю, что должен быть лучший способ сделать это. Какой-то способ сделать условный расчет каждого запроса, чтобы его можно было суммировать в запросе, а не в моем неуклюжем решении PHP? Есть идеи? Спасибо всем, у кого хватило терпения хотя бы прочитать это далеко, я знаю, что это ПИТА вопроса. Любая помощь с благодарностью!
function calculate_public_records()
{
$total_req_total = 0;
$total_funded_total = 0;
$total_cutback_total = 0;
$organizations = array();
foreach($this->organizations as $org)
{
$id = $org['OrgID'];
$org_req_total = 0;
$org_funded_total = 0;
$org_cutback_total = 0;
$cycles = array();
foreach($this->cycles as $cycle)
{
$cycle_req_total = 0;
$cycle_funded_total = 0;
$cycle_cutback_total = 0;
$cycle_requests = array();
foreach($this->request_types as $type)
{
$reqs = $this->funding_request_model->getRequests($type, $cycle['CycleID'], $id);
foreach($reqs as $r)
{
$cutback = $cycle['NonUnityCutBack'];
if ($type == "Event") $cutback = ($r->UnityReq == 1) ? $cycle['UnityCutBack'] : $cutback;
$cutback = ($r->PerOff != 0) ? $r->PerOff : $cutback;
$request = array();
$request['id'] = $r->ReqID;
$request['type'] = $type;
$request['name'] = $r->Title;
$request['requested'] = number_format($r->RequestTotal, 2);
$request['funded'] = number_format($r->AmtFunded, 2);
$request['cutback'] = number_format(($r->AmtFunded - ($r->AmtFunded * $cutback)), 2);
$cycle_req_total += $request['requested'];
$cycle_funded_total += $request['funded'];
$cycle_cutback_total += $request['cutback'];
$cycle_requests[] = $request;
}
}
$cycle_totals = array();
$cycle_totals['requested'] = number_format($cycle_req_total, 2);
$cycle_totals['funded'] = number_format($cycle_funded_total, 2);
$cycle_totals['cutback'] = number_format($cycle_cutback_total, 2);
$org_req_total += $cycle_req_total;
$org_funded_total += $cycle_funded_total;
$org_cutback_total += $cycle_cutback_total;
$cycles[] = array('name' => $cycle['CycleName'], 'requests' => $cycle_requests, 'totals' => $cycle_totals);
}
$org_totals = array();
$org_totals['requested'] = number_format($org_req_total, 2);
$org_totals['funded'] = number_format($org_funded_total, 2);
$org_totals['cutback'] = number_format($org_cutback_total, 2);
$total_req_total += $org_req_total;
$total_funded_total += $org_funded_total;
$total_cutback_total += $org_cutback_total;
$organizations[] = array('id' => $org['OrgID'], 'name' => $org['Organization'], 'cycles' => $cycles, 'totals' => $org_totals);
}
$totals = array();
$totals['requested'] = number_format($total_req_total, 2);
$totals['funded'] = number_format($total_funded_total, 2);
$totals['cutback'] = number_format($total_cutback_total, 2);
return array('organizations' => $organizations, 'totals' => $totals);
Сводка расчета:
# For tables AdministrativeRequests, CapitalRequests & EventRequests, calculate:
SUM(AmountRequested)
SUM(AmountFunded)
# For tables AdministrativeRequests, CapitalRequests & EventRequests, calculate:
AmountAfterCutback = AmountFunded - (AmountFunded * Cutback)
# Cutback calculation pseudocode
if( <table>.PerOff > 0 ) {
Cutback = <table>.PerOff
} elseif ( <table> == EventRequests && EventRequests.UnityReq == 1 ) {
Cutback = FundingCycles.UnityCutBack
} else {
Cutback = FundingCycles.NonUnityCutBack
}