简单的mySQL子查询

时间:2011-11-17 21:20:30

标签: mysql

我有一个简单的问题,但我是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;

任何人都有贡献吗? 我将不胜感激任何帮助。

2 个答案:

答案 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