我的目标是只显示尚未收到所有产品的采购订单。
我有一个名为test_po
的主表和另外两个表test_po_bom
、test_rog_bom
。test_po_bom
和test_rog_bom
表是我存储产品列表的地方。test_po_bom
是我订购的产品列表,test_rog_bom
是我收到的产品列表。
基本上:loop purchase_orders WHERE products_received < products_ordered
表格结构:
table `test_po`: `ID`, `vendor_ID`
table `test_po_bom`: `ID`, `po_ID`, `product_ID`, `quantity`
table `test_rog_bom`: `ID`, `po_ID`, `product_ID`, `quantity`
代码:
$SQL = "SELECT
*,
test_po.ID AS test_po_ID
FROM
test_po
LEFT JOIN test_po_bom ON test_po_bom.po_ID=test_po.ID
LEFT JOIN test_rog_bom ON test_rog_bom.po_ID=test_po.ID
WHERE
(SELECT SUM(quantity) FROM test_rog_bom WHERE po_ID=test_po.ID) < (SELECT SUM(quantity) FROM test_po_bom WHERE po_ID=test_po.ID)";
$result = mysql_query($SQL) or die(mysql_error());
while($row = mysql_fetch_array($result))
{
echo $row['test_po_ID'].'<br>';
}
它不会吐出任何东西,我尝试过很多不同的变体,但我就是想不通。
问题似乎出在您的查询上。不要使用*
,而是指定所需的列。以下解决方案使用别名来帮助提高代码的可读性,尤其是使用类似名称的代码。您还会注意到HAVING而不是WHERE。
SELECT
p.ID as PO_ID
,p.VENDOR_ID
,pb.product_ID as PRODUCT_ID
,SUM(pb.quantity) as QUANTITY_ORDERED
,SUM(rb.quantity) as QUANTITY_RECEIVED
FROM test_po as p
LEFT JOIN test_po_bom as pb ON pb.po_ID = p.ID
LEFT JOIN test_rog_bom as rb ON rb.po_ID = p.ID
GROUP BY
p.ID
,p.VENDOR_ID
,pb.product_ID
HAVING SUM(rb.quantity) < SUM(pb.quantity)
这是未验证的代码 我很抱歉发布了未经测试的代码,但我现在无法测试它,我认为这表明了一些事情,即使它不完全正确,你也可以尝试不同的方法。
试试这个:
select po.ID, po_bom.quant n_ordered, rog_bom.quant n_received
from test_po po
left join (select po_ID, sum(quantity) as quant from test_po_bom group by po_ID) po_bom
on po.ID = po_bom.po_ID
left join (select po_ID, sum(quantity) as quant from test_rog_bom group by po_ID) rog_bom
on po.ID = rog_bom.po_ID
where coalesce(rog_bom.quant, 0) < coalesce(po_bom.quant, 0);
这改变了你做这些事情的方式:
- 使用表别名可以清楚地指定哪些引用引用同一个表行
- 使用分组依据按ID聚合总和
- 使用联合来处理至少有一个表(可能是test_rog_bom)没有ID行的情况。我怀疑这实际上是问题的根源