php - 如何使用 PHP 和 MySQL 从两个条件链接表中有效地求和和减去

标签 php mysql performance

下面的查询是否有更有效的解决方案。我已尝试尽我所能研究该主题,但很难知道实际要搜索什么...

$tenant_balance = 0;

$total_charge_amount_query = mysqli_query($con, "
    SELECT  tenant_charge_id, tenant_charge_total_amount
        FROM  accounts_tenant_charge
        WHERE  tenant_charge_tenancy_id='{$tenancy_details['tenancy_id']}'"
     ) or die(mysql_error());  

while($total_charge_amount_row = mysqli_fetch_array( $total_charge_amount_query )) {

    $tenant_balance = $tenant_balance +  $total_charge_amount_row['tenant_charge_total_amount'];

    $total_payment_amount_query = mysqli_query($con, "
        SELECT  tenant_charge_payment_amount
            FROM  accounts_tenant_charge_payment
            WHERE  tenant_charge_payment_tenant_charge_id =
                    '{$total_charge_amount_row['tenant_charge_id']}"
                 ) or die(mysql_error());

    while($total_payment_amount_row = mysqli_fetch_array( $total_payment_amount_query )) {

        $tenant_balance = $tenant_balance - $total_payment_amount_row['tenant_charge_payment_amount'];

    }
}

echo '£' . number_format($tenant_balance, 2, '.', ',');

我在下面添加了数据库表结构和一些数据。

表 #1

-- phpMyAdmin SQL Dump
-- version 4.0.10.7
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jun 16, 2015 at 01:50 PM
-- Server version: 5.1.73-cll
-- PHP Version: 5.4.23

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

--
-- Database: `propsyst_atlas`
--

-- --------------------------------------------------------

--
-- Table structure for table `accounts_tenant_charge`
--

CREATE TABLE IF NOT EXISTS `accounts_tenant_charge` (
  `tenant_charge_id` int(11) NOT NULL AUTO_INCREMENT,
  `tenant_charge_date` date DEFAULT NULL,
  `tenant_charge_payment_terms` tinyint(4) DEFAULT NULL,
  `tenant_charge_tenancy_id` int(11) DEFAULT NULL,
  `tenant_charge_notes` text COLLATE utf8_bin,
  `tenant_charge_total_amount` decimal(10,2) DEFAULT NULL,
  `tenant_charge_date_created` date DEFAULT NULL,
  `tenant_charge_date_updated` date DEFAULT NULL,
  `tenant_charge_created_by` int(11) DEFAULT NULL,
  `tenant_charge_updated_by` int(11) DEFAULT NULL,
  PRIMARY KEY (`tenant_charge_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=17 ;

--
-- Dumping data for table `accounts_tenant_charge`
--

INSERT INTO `accounts_tenant_charge` (`tenant_charge_id`, `tenant_charge_date`, `tenant_charge_payment_terms`, `tenant_charge_tenancy_id`, `tenant_charge_notes`, `tenant_charge_total_amount`, `tenant_charge_date_created`, `tenant_charge_date_updated`, `tenant_charge_created_by`, `tenant_charge_updated_by`) VALUES
(15, '2015-06-22', 1, 25, '', '180.00', '2015-06-14', '2015-06-14', 1, 1),
(14, '2015-06-15', 1, 25, '', '550.00', '2015-06-14', '2015-06-14', 1, 1),
(16, '2015-06-27', 1, 25, '', '10.00', '2015-06-14', '2015-06-14', 1, 1);

表 #2

-- phpMyAdmin SQL Dump
-- version 4.0.10.7
-- http://www.phpmyadmin.net
--
-- Host: localhost
-- Generation Time: Jun 16, 2015 at 01:51 PM
-- Server version: 5.1.73-cll
-- PHP Version: 5.4.23

SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO";
SET time_zone = "+00:00";

--
-- Database: `propsyst_atlas`
--

-- --------------------------------------------------------

--
-- Table structure for table `accounts_tenant_charge_payment`
--

CREATE TABLE IF NOT EXISTS `accounts_tenant_charge_payment` (
  `tenant_charge_payment_id` int(11) NOT NULL AUTO_INCREMENT,
  `tenant_charge_payment_date` date DEFAULT NULL,
  `tenant_charge_payment_amount` decimal(10,2) DEFAULT NULL,
  `tenant_charge_payment_method` tinyint(4) DEFAULT NULL,
  `tenant_charge_payment_tenant_charge_id` int(11) DEFAULT NULL,
  `tenant_charge_payment_notes` text COLLATE utf8_bin,
  `tenant_charge_payment_date_created` date DEFAULT NULL,
  `tenant_charge_payment_date_updated` date DEFAULT NULL,
  `tenant_charge_payment_created_by` int(11) DEFAULT NULL,
  `tenant_charge_payment_updated_by` int(11) DEFAULT NULL,
  PRIMARY KEY (`tenant_charge_payment_id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=12 ;

--
-- Dumping data for table `accounts_tenant_charge_payment`
--

INSERT INTO `accounts_tenant_charge_payment` (`tenant_charge_payment_id`, `tenant_charge_payment_date`, `tenant_charge_payment_amount`, `tenant_charge_payment_method`, `tenant_charge_payment_tenant_charge_id`, `tenant_charge_payment_notes`, `tenant_charge_payment_date_created`, `tenant_charge_payment_date_updated`, `tenant_charge_payment_created_by`, `tenant_charge_payment_updated_by`) VALUES
(9, '2015-06-15', '550.00', 2, 14, '', '2015-06-14', '2015-06-14', 1, 1),
(10, '2015-06-22', '50.00', 2, 15, '', '2015-06-16', '2015-06-16', 1, 1);

最佳答案

我想重点是摆脱几个查询和两个 PHP 循环。无需循环,此查询可在一个 SQL 查询中计算总费用、付款和余额:

SELECT
    tenant_charge_tenancy_id,
    sum(tenant_charge_total_amount) as charge,
    IFNULL(sum(payments.payment), 0) as payment,
    sum(tenant_charge_total_amount) - IFNULL(sum(payments.payment), 0) as balance
FROM accounts_tenant_charge
LEFT OUTER JOIN (
    SELECT
        tenant_charge_payment_tenant_charge_id,
        sum(tenant_charge_payment_amount) as payment
    FROM accounts_tenant_charge_payment
    GROUP BY tenant_charge_payment_tenant_charge_id
) as payments ON tenant_charge_id = tenant_charge_payment_tenant_charge_id
WHERE tenant_charge_tenancy_id= 25
GROUP BY tenant_charge_tenancy_id

您可以将 $tenancy_details['tenancy_id'] 放入您的 PHP 代码中,而不是 25。通过删除 WHERE tenant_charge_tenancy_id= ...,您可以使用此查询来获取所有余额。

关于php - 如何使用 PHP 和 MySQL 从两个条件链接表中有效地求和和减去,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30867591/

相关文章:

php - 循环父记录,然后是子记录,父记录和子记录等

mysql - 在 MySQL 中存储 CLLocationDegrees 时精度丢失

c# - 写入后是否必须优化lucene索引?

php - Doctrine ManyToMany 优化许多查询

php - 如何更新 Doctrine MongoDB 中的嵌入文档?

php - Foundation- Contact Form 调整

php - mysql_insert_id() 总是返回 0

创建多对多关系时出现 MySQL 错误 #1215

javascript - 从服务器端返回 Javascript 对象有什么好处?

performance - 为什么我的 CUDA 内核执行时间会随着连续启动而增加?