Php MySQL查询以显示所有已付款和未付款发票,其中发票可以有多个付款
我有两张桌子,请看下面的结构。基本上,使用MySQL/PHP,我需要构造两个查询。一个用于显示已付款发票的列表,另一个用于显示未付款发票。一张发票可以有多笔付款。例如,一张100英镑的发票可以使用不同金额的任意数量的付款进行支付。发票也可以没有付款,这意味着全额余额未付 你能帮我查询一下吗 我自己也尝试过这个问题(参见),但我没有提到一张发票可以有多笔付款 表结构Php MySQL查询以显示所有已付款和未付款发票,其中发票可以有多个付款,php,mysql,Php,Mysql,我有两张桌子,请看下面的结构。基本上,使用MySQL/PHP,我需要构造两个查询。一个用于显示已付款发票的列表,另一个用于显示未付款发票。一张发票可以有多笔付款。例如,一张100英镑的发票可以使用不同金额的任意数量的付款进行支付。发票也可以没有付款,这意味着全额余额未付 你能帮我查询一下吗 我自己也尝试过这个问题(参见),但我没有提到一张发票可以有多笔付款 表结构 CREATE TABLE IF NOT EXISTS `accounts_invoice` ( `invoice_id` int
CREATE TABLE IF NOT EXISTS `accounts_invoice` (
`invoice_id` int(11) NOT NULL AUTO_INCREMENT,
`invoice_customer_type` tinyint(4) DEFAULT NULL,
`invoice_customer` int(11) DEFAULT NULL,
`invoice_date` date DEFAULT NULL,
`invoice_due_date` date DEFAULT NULL,
`invoice_property_id` int(11) DEFAULT NULL,
`invoice_tenancy_id` int(11) DEFAULT NULL,
`invoice_branch` int(11) DEFAULT NULL,
`invoice_payment_terms` tinyint(4) DEFAULT NULL,
`invoice_notes` text COLLATE utf8_bin,
`invoice_total_amount_exc_vat` decimal(10,2) DEFAULT NULL,
`invoice_total_vat_amount` decimal(10,2) DEFAULT NULL,
`invoice_posted` tinyint(4) DEFAULT '0',
`invoice_date_created` datetime DEFAULT NULL,
`invoice_date_updated` datetime DEFAULT NULL,
`invoice_date_posted` datetime DEFAULT NULL,
`invoice_created_by` int(11) DEFAULT NULL,
`invoice_updated_by` int(11) DEFAULT NULL,
`invoice_posted_by` int(11) DEFAULT NULL,
PRIMARY KEY (`invoice_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=87 ;
CREATE TABLE IF NOT EXISTS `accounts_invoice_payment` (
`invoice_payment_id` int(11) NOT NULL AUTO_INCREMENT,
`invoice_payment_date` date DEFAULT NULL,
`invoice_payment_amount` decimal(10,2) DEFAULT NULL,
`invoice_payment_method` tinyint(4) DEFAULT NULL,
`invoice_payment_invoice_id` int(11) DEFAULT NULL,
`invoice_payment_notes` text COLLATE utf8_bin,
`invoice_payment_date_created` datetime DEFAULT NULL,
`invoice_payment_date_updated` datetime DEFAULT NULL,
`invoice_payment_created_by` int(11) DEFAULT NULL,
`invoice_payment_updated_by` int(11) DEFAULT NULL,
PRIMARY KEY (`invoice_payment_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_bin AUTO_INCREMENT=71 ;
也许是这样的?我有两个问题
<?php
try
{
$s = $conn->query("SELECT * from accounts_invoice");
}
catch(PDOException $e)
{
echo $e->getMEssage();
}
try
{
$p = $conn->prepare("SELECT * from accounts_invoice_payment where invoice_payment_invoice_id = :id");
}
catch(PDOException $e)
{
echo $e->getMEssage();
}
while($main_invoies = $s->fetch(PDO::FETCH_OBJ))
{
$invc_sum=0;
$invoiceid = $main_invoies->invoice_id;
$totalAmount = ($main_invoies->invoice_total_amount_exc_vat) + ($main_invoies->invoice_total_vat_amount);
$p->bindParam(':id', $invoiceid);
while($sub_invoices = $p->fetch(PDO::FETCH_OBJ))
{
$invc_sum = $invc_sum + ($sub_invoices->invoice_payment_amount);
}
if($invc_sum == $totalAmount)
{
echo "Invoice Paid";
}
else
{
echo "Invoice unpaid";
}
}
?>
尽可能少地使用PHP。它不是db引擎。即使在中等大小的数据集上,它也会产生巨大的阻力 模式: 一次完成所有任务: 逾期的: 全额支付: 信用证到期日:
选择i.invId、i.invAmt、ifnull(金额(p.amt)、0)作为已付,i.invAmt-ifnull(金额(p.amt)、0)作为到期
从发票一
左连接付款
关于p.invId=i.invId
其中i.custId=101
因维人分组
到期我自己也尝试过查询
查询在哪里?发票付款发票id
=发票id
?您的数据和预期结果是什么?Michael当它们都自动递增时,如何发票付款发票id==发票id
相同的查询将显示所有已付款。负应付AMT是超额支付。祝你好运你是说“WHERE due=0”?是的,我相信你在去之前不能在查询中引用“due”。测试了所有4个。你可能需要一个或两个非常好的工作,谢谢!工作完美,是一个非常有效的解决方案!您的查询仍然返回所有发票,然后使用if语句处理它们。我希望查询只返回所有已付或未付发票。请上传一些测试数据好吗?您的解决方案确实有效,但效率不如公认的答案。@MichaelLB很高兴您找到了解决方案:)它确实有效,只是速度不如akshay。永远不要在php中做mysql可以做得更快的事情。想象一下10k行返回,而sql会给你答案。PHP是一件很棒的事情。。。一个高性能的数据库引擎,它不是
CREATE TABLE invoice
(
invId int auto_increment primary key,
custId int(11) not null,
invAmt decimal(10,2) not null
);
CREATE TABLE payment
(
pdId int auto_increment primary key,
invId int not null,
amt decimal(10,2) not null
);
-- NOTE you need foreign key (FK) constraints on your real table
insert invoice (custId,invAmt) values (101,9999); -- 1
insert invoice (custId,invAmt) values (101,100); -- 2
insert invoice (custId,invAmt) values (101,40); -- 3
insert invoice (custId,invAmt) values (101,20); -- 4
insert invoice (custId,invAmt) values (201,100); -- 5
truncate table payment;
insert payment (invId,amt) values (1,10); -- inv 1 pymt
insert payment (invId,amt) values (1,20); -- inv 1 pymt
insert payment (invId,amt) values (1,30); -- inv 1 pymt
insert payment (invId,amt) values (2,30); -- inv 2 pymt
insert payment (invId,amt) values (2,70); -- inv 2 pymt, now paid in full
insert payment (invId,amt) values (3,99); -- inv 3 Overpayment
select i.invId,i.invAmt,ifnull(sum(p.amt),0) as paid,i.invAmt-ifnull(sum(p.amt),0) as due
from invoice i
left join payment p
on p.invId=i.invId
where i.custId=101
group by i.invId
order by i.invId
select i.invId,i.invAmt,ifnull(sum(p.amt),0) as paid,i.invAmt-ifnull(sum(p.amt),0) as due
from invoice i
left join payment p
on p.invId=i.invId
where i.custId=101
group by i.invId
having due>0
order by i.invId
+-------+---------+-------+---------+
| invId | invAmt | paid | due |
+-------+---------+-------+---------+
| 1 | 9999.00 | 60.00 | 9939.00 |
| 4 | 20.00 | 0.00 | 20.00 |
+-------+---------+-------+---------+
select i.invId,i.invAmt,ifnull(sum(p.amt),0) as paid,i.invAmt-ifnull(sum(p.amt),0) as due
from invoice i
left join payment p
on p.invId=i.invId
where i.custId=101
group by i.invId
having due=0
order by i.invId
+-------+--------+--------+------+
| invId | invAmt | paid | due |
+-------+--------+--------+------+
| 2 | 100.00 | 100.00 | 0.00 |
+-------+--------+--------+------+
select i.invId,i.invAmt,ifnull(sum(p.amt),0) as paid,i.invAmt-ifnull(sum(p.amt),0) as due
from invoice i
left join payment p
on p.invId=i.invId
where i.custId=101
group by i.invId
having due<0
order by i.invId