Неверное вычисление Foreach в foreach

#php #foreach

#php #foreach

Вопрос:

У меня есть две таблицы. Один из них называется «клиент», а другой — «текущий счет».

Я хочу сделать; Собрать столбцы debit и credit в таблице текущих счетов из данных, записанных в таблице customer, и вывести результат. Но почему-то я не могу выполнить правильный расчет. Я оставляю свои примеры кодов ниже.

Заранее благодарю вас за вашу поддержку.

 Table Name : Customer                    Table name : Current Account

| tax | company_name                     |tax_no| debt | take
______________________                  _________________________
| 1234| Company One                      |1234  | 9    |
| 5678| Company Second                   |1234  |      | 3
                                         |1234  | 15   |
                                         |5678  | 4    |
                                         |5678  |      | 1
  

Согласно приведенной выше таблице, я хочу объединить данные в таблице текущих счетов в соответствии с данными в таблице customer, взять задолженность из дебиторской задолженности и получить результат.

 // Data list
$sql = $db->query("SELECT*FROM customer ORDER BY company_name ASC");

$sum_debt = 0;
$sum_take = 0;
foreach($sql->results() as item){

$tax = $item->tax;
$current = $db->query("SELECT*FROM current_account WHERE tax_no = '$tax' ");
foreach($current->results() as $row){
    $sum_debt  = $row->debt;
    $sum_take  = $row->take;
     
     $res = $sum_take - $sum_debt;
}

}

  

Результат всегда неверный. Он делает вывод, выполняя правильную операцию с первыми данными. Он собирает первый результат поверх следующих данных.

Результаты, которые должны быть получены в соответствии с таблицей; первая компания: -24, вторая компания -3, но вторые данные -27.

Комментарии:

1. Вам нужно переместиться $sum_debt = 0; $sum_take = 0; внутрь первого цикла, чтобы он сбрасывался для каждого клиента

2. Почему это помечено как .htaccess ?

Ответ №1:

Если вы хотите рассчитать общую сумму для каждой компании, вам следует сбросить долг и взять для каждой новой компании и переместить строку $ res = $sum_take — $sum_debt; из внутреннего foreach во внешний foreach и сохранить результат для каждой компании, для которой он рассчитан.

 // Data list
$sql = $db->query("SELECT*FROM customer ORDER BY company_name ASC");

$sum_debt = 0;
$sum_take = 0;
foreach($sql->results() as item)
{
    $sum_debt = 0;
    $sum_take = 0;
    $tax = $item->tax;
    current = $db->query("SELECT*FROM current_account WHERE tax_no = '$tax' ");
    foreach($current->results() as $row){
          $sum_debt  = $row->debt;
          $sum_take  = $row->take;
    }
    $res = $sum_take - $sum_debt;
    //Save or print res
    echo $tax . " has debt: " . $res; 
}
  

Я бы также настоятельно рекомендовал получить все необходимые вычисленные данные в первом SQL-запросе. Выполнение запроса для каждой компании может быть дорогостоящим и приводить к снижению производительности. SQL будет выглядеть примерно так:

 SELECT c.tax, 
       c.company_name, 
       (SELECT SUM(take) FROM [Current Amount] WHERE tax_no = tax) - 
       (SELECT SUM(debt) FROM [Current Amount] WHERE tax_no = tax) AS [res] 
FROM Company
  

Комментарии:

1. Спасибо за поддержку

Ответ №2:

Если $res должен содержать текущий баланс счета клиента, вам необходимо переместить вычисление $res за пределы внутреннего цикла for и сбросить значения sum_debt и sum_take для каждого клиента:

 $sql = $db->query("SELECT*FROM customer ORDER BY company_name ASC");

//for loop for each customer
foreach($sql->results() as item){
    
    $sum_debt = 0; //debt of this customer
    $sum_take = 0; //credit of this customer

    $tax = $item->tax;
    $current = $db->query("SELECT*FROM current_account WHERE tax_no = '$tax' ");
    foreach($current->results() as $row){
        $sum_debt  = $row->debt;
        $sum_take  = $row->take;
    }
     
    $res = $sum_take - $sum_debt; //account balance of this customer

}
  

Кроме того, вы можете упростить свой код, напрямую рассчитав баланс учетной записи:

 $sql = $db->query("SELECT*FROM customer ORDER BY company_name ASC");

//for loop for each customer
foreach($sql->results() as item){
    
    $balance_of_this_customer = 0;

    $tax = $item->tax;
    $current = $db->query("SELECT*FROM current_account WHERE tax_no = '$tax' ");
    foreach($current->results() as $row){
        $balance_of_this_customer -= $row->debt;
        $balance_of_this_customer  = $row->take;
    }

}
  

Ответ №3:

Я думаю, вы могли бы сделать это одним SQL-запросом и без запроса в цикле.

 SELECT customer.company_name, customer.tax, SUM(current_account.debt) AS total_debt, SUM(current_account.take) AS total_take FROM customer LEFT JOIN current_account ON current_account.tax_no = customer.tax GROUP BY customer.tax
  

Комментарии:

1. Вы также можете определить «баланс» в запросе. ВЫБЕРИТЕ customer.company_name, customer.tax, SUM(current_account.debt) В КАЧЕСТВЕ total_debt, SUM(current_account.take) В КАЧЕСТВЕ total_take, (total_debt — total_take) В КАЧЕСТВЕ баланса СЛЕВА ОТ клиента ПРИСОЕДИНИТЕ current_account К current_account.tax_no = customer.tax GROUP ПО customer.tax

Ответ №4:

попробуйте это. я исправил вашу проблему и отредактировал ваш код с лучшим синтаксисом, конечно, по моему мнению

 $data = array();

$customers = $db->query("SELECT * FROM `customer` ORDER BY `company_name` ASC");
$customers = $customers->results();

$result = 0;

foreach($customers as $customer){
    
    if(!isset($data[$customer['id']])){

        $data[$customer['id']] = array(
            'balance' => 0,
            'debt' => 0,
            'take' => 0
        );

    }

    $accounts = $db->query("SELECT * FROM `current_account` WHERE `tax_no` = '" . $customer->tax . "'");
    $accounts = $accounts->results();

    foreach($accounts as $account){

        $data[$customer['id']]['take']  = $row->take;

        $data[$customer['id']]['debt']  = $row->debt;

        $data[$customer['id']]['balance'] = $data[$customer['id']]['take'] - $data[$customer['id']]['debt'];

    }

}

print_r($data);