我有一个简单的问题,但我是SQL的新手,所以请原谅我的无知。
我有一份会计报告,它会计算所欠余额,并累计余额,以便向我报告特定期间的未偿还总额。问题是每个JOB都有很多发票提供运行总计/余额,因此当我当前查询累加余额时它显示天价很高的未结金额,我们发现当前代码正在添加余额所有发票。 例- 如果JOB ID 001有四张发票 - I-001余额200, I-002余额100, I-003余额50, I-004余额0。
它会告诉我有350美元的未付款,而实际上它是零。
我能想到的解决方案(我不知道如何编码)是按作业ID对结果进行分组,并使用MAX功能仅为每个JOBID选择最高ID
我遇到的问题是余额不会保存到表格中,而是在每次需要时重新计算。您可以建议只向我显示特定JOBID的最高发票ID的余额 我的发票表包含以下列:
1 ID int(11)
2 ParentID int(11)
3 JOBID varchar(100)
4 DATE date
5 LENSES decimal(10,2)
6 FRAMES decimal(10,2)
7 TAXABLEGOODS decimal(10,2)
8 DISCOUNT decimal(10,2)
9 PREVIOUSBALANCE decimal(10,2)
10 PAYMENT decimal(10,2)
11 PAYMENTTYPE varchar(200)
12 NOTES varchar(255)
13 PMA decimal(10,2)
目前的代码如下:
$pieces = explode("-", $_REQUEST["STARTDATE"]);
$startDate=$pieces[2] . "-" . $pieces[1] . "-" . $pieces[0];
if($_REQUEST["ENDDATE"]==""){
$endDate=0;
}else{
$pieces = explode("-", $_REQUEST["ENDDATE"]);
$endDate = $pieces[2] . "-" . $pieces[1] . "-" . $pieces[0];
}
$result = mysql_query("SELECT * FROM INVOICES WHERE DATE BETWEEN '" . $startDate . "' AND '" . $endDate . "'");
$totalCount = 0;
$total = 0;
$allPayments= 0;
$pmtTypes = Array();
$totalHST = 0;
$outstanding=0;
$payments=0;
while($theRow=mysql_fetch_array($result)){
$allPayments += $theRow["PAYMENT"];
if($theRow["PAYMENTTYPE"] == "") $theRow["PAYMENTTYPE"] = "BLANK";
if(isset($pmtTypes[$theRow["PAYMENTTYPE"]])){
$pmtTypes[$theRow["PAYMENTTYPE"]] += $theRow["PAYMENT"];;
}else{
$pmtTypes[$theRow["PAYMENTTYPE"]] = $theRow["PAYMENT"];;
}
if($theRow["PREVIOUSBALANCE"] != 0) continue;
$subTotal = ( ( $theRow["LENSES"] + $theRow["FRAMES"] + $theRow["TAXABLEGOODS"] ) - $theRow["DISCOUNT"]);
$HST = ( $theRow["TAXABLEGOODS"] * 0.13 );
$totalHST+= $HST;
$total += ( $subTotal + $HST );
$payments+=$theRow["PAYMENT"];
}
$outstanding=$total-$payments;
任何人都有贡献吗? 我将不胜感激任何帮助。
答案 0 :(得分:0)
仅显示特定JOBID的最高发票ID的余额
对于单个职位ID:
SELECT lenses+frames+taxablegoods-discount+previousbalance AS balance
FROM invoices WHERE jobid=?
ORDER BY id DESC LIMIT 1
按作业ID对结果进行分组,并使用MAX功能仅为每个JOBID选择最高ID
如果您想一次查询多个作业的最新发票,您所说的是每组最大选择。 SQL并不像你希望的那样容易做到这一点。有various approaches,包括子查询,但在MySQL上我通常支持null-self-join:
SELECT i0.jobid, i0.lenses+...etc... AS balance
FROM invoices AS i0 LEFT JOIN invoices AS i1 ON i1.jobib=i0.jobid AND i1.id>i0.id
WHERE i1.id IS NULL
即:“给我行,其中没有具有相同作业ID但发票ID更高的行”。
如果在两个日期之间执行此操作,则需要将条件应用于联接的两侧:
SELECT i0.jobid, i0.lenses+...etc... AS balance
FROM invoices AS i0 LEFT JOIN invoices AS i1 ON
i1.jobib=i0.jobid AND i1.id>i0.id AND
i1.date BETWEEN ? AND ?
WHERE
i0.date BETWEEN ? AND ?
i1.id IS NULL
顺便提一下,将字符串放入查询时会出现SQL注入漏洞。使用mysql_real_escape_string()
或更好的参数化查询来避免这些问题。
答案 1 :(得分:0)
子查询看起来像这样:
SELECT * FROM INVOICES I1
WHERE DATE BETWEEN ? AND ?
AND ID = (SELECT MAX(ID) FROM INVOICES I2
WHERE DATE BETWEEN ? AND ?
AND I2.JOBID = I1.JOBID)
您应该研究使用参数化查询,而不是将字符串与用户输入连接起来。至少使用mysql_real_escape_string - 见这里:http://www.php.net/manual/en/function.mysql-real-escape-string.php