除了表上的索引以优化连接之外,您还可以对 S.ItemID 进行分组,而不是仅使用 IT.UID,因为这是连接基础,并且是查询的主 FROM 表的一部分......如果这是 items 表上的可用索引,请使用它,您就完成了。无需引用 group by 中的 sales_items 或 inventory 列名称。
现在,话虽如此,如果您从 sales_items 和库存中汇总的相同“item id”有多个记录,您将遇到的另一个问题是笛卡尔结果,因为我已经非常简化了一个示例你通过
CREATE TABLE items (
`uid` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(5) NOT NULL,
PRIMARY KEY (`uid`)
);
CREATE TABLE sales_items (
`sid` int(11) NOT NULL AUTO_INCREMENT,
`itemid` int(11),
`qty` int(5) NOT NULL,
PRIMARY KEY (`sid`),
KEY byItemAndQty (`itemid`,`qty`)
);
CREATE TABLE inventory (
`iid` int(11) NOT NULL AUTO_INCREMENT,
`uid` int(11) NOT NULL,
`qty` int(5) NOT NULL,
PRIMARY KEY (`iid`),
KEY byItemAndQty (`itemid`,`qty`)
);
insert into items ( uid, name ) values ( 1, 'test' );
INSERT INTO sales_items ( sid, itemid, qty ) VALUES ( 1, 1, 1 );
INSERT INTO sales_items ( sid, itemid, qty ) VALUES ( 2, 1, 2 );
INSERT INTO inventory ( iid, uid, qty ) VALUES ( 1, 1, 13 );
INSERT INTO inventory ( iid, uid, qty ) VALUES ( 2, 1, 35 );
简单 1 项,销售项 2 项记录 1.. 数量 1 和 2,总计 = 3 库存 2 条记录,项目 1.. 数量 13 和 35,总计 38
SELECT
it.uid,
it.Name,
sum(i.Qty) as iQty,
sum(s.Qty) as sQty,
COALESCE( sum(i.Qty),0) - COALESCE(sum(s.Qty),0) as stock
FROM
items it
left outer join sales_items s
on it.uid = s.ItemID
left outer join inventory i
on it.uid = i.uid
group by
it.uid
因此,您可能期望 Stock 的查询结果是
uid name iQty sQty stock
1 test 48 3 45
but in reality becomes
1 test 96 6 90
现在...请注意我的假设,但请从多个这样的表中查看类似的 sum()s 或 count()s。我假设 ITEMS 表是每个项目的一条记录。
Sales_Items 实际上有比提供的更多的列(例如销售详细信息和可以跟踪的每个日期/销售计数)并且可能包含给定项目 id 的多个销售记录数量(因此与我的示例匹配)。最后,库存表同样可以每个相同项目有多个记录,例如按日期跟踪的进货库存购买,因此每个给定项目 ID 有多个记录(也与我的示例相匹配)。
为了防止这种类型的笛卡尔结果,并且还可以提高速度,我会对每个辅助表进行预聚合并加入到该表中。
SELECT
it.uid,
it.Name,
i.iQty,
s.sQty,
COALESCE( i.iQty,0) - COALESCE(s.sQty,0) as stock
FROM
items it
left join ( select itemid, sum( qty ) as SQty
from sales_items
group by itemid ) s
on it.uid = s.ItemID
left join ( select uid, sum( qty ) as IQty
from inventory
group by uid ) i
on it.uid = i.uid
group by
it.uid
你得到正确的值
uid name iQty sQty stock
1 test 48 3 45
是的,这仅用于单个项目 ID 来证明这一点,但仍适用于您拥有的尽可能多的库存项目以及某些项目可能(或不存在)存在的相应销售/库存记录。