次のように3つのテーブルがあります。
products:[product_id,product_name]
stock:[product_id,date,qty_received]
sales:[product_id,date,qty_sold]
qty_received - qty_sold を引いて、すべての製品の残高を表示しようとしています。私のクエリは次のとおりです。
SELECT DISTINCT p.product_id, p.product_name,
IFNULL(sum(qty_received),0)-IFNULL(sum(qty_sold),0) as balance FROM products p
LEFT JOIN stock st ON (p.product_id=st.product_id)
LEFT JOIN sales sa ON (p.product_id=sa.product_id)
GROUP BY p.product_id
上記のクエリでは、正しい残高が得られません。助けてください。
追加情報: 以下は、私のテーブル Products テーブルの簡略化された構造です。
CREATE TABLE IF NOT EXISTS `products` (
`product_id` varchar(15) NOT NULL,
`product_name` varchar(20) NOT NULL,
UNIQUE KEY `product_id` (`product_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- テーブルのデータをダンプしていますproducts
INSERT INTO `products` (`product_id`, `product_name`) VALUES
('111', 'Product One'),
('222', 'Product Two'),
('333', 'Product Three'),
('444', 'Product Four');
在庫表:
CREATE TABLE IF NOT EXISTS `stock` (
`stock_id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`qty_received` int(11) NOT NULL,
PRIMARY KEY (`stock_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=112 ;
-- テーブルのデータをダンプしていますstock
INSERT INTO `stock` (`stock_id`, `product_id`, `qty_received`) VALUES
(1, 111, 5),
(2, 222, 10),
(3, 333, 4),
(4, 444, 6),
(5, 111, 2),
(6, 222, 7),
(7, 111, 3),
(8, 111, 3);
売上表
CREATE TABLE IF NOT EXISTS `sales` (
`sales_id` int(11) NOT NULL AUTO_INCREMENT,
`product_id` int(11) NOT NULL,
`qty_sold` int(11) NOT NULL,
PRIMARY KEY (`sales_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
-- テーブルのデータをダンプしていますsales
INSERT INTO `sales` (`sales_id`, `product_id`, `qty_sold`) VALUES
(1, 111, -1),
(2, 222, -3),
(3, 333, -2),
(4, 111, -3),
(5, 222, -1),
(6, 222, -4);
私が得ている結果は次のとおりです。
+------------+--------------+---------+
| product_id | product_name | balance |
+------------+--------------+---------+
| 111 | Product One | 10 |
| 222 | Product Two | 35 |
| 333 | Product Three| 2 |
| 444 | Product Four | 6 |
+------------+--------------+---------+
私が期待している正しいバランスは
+------------+--------------+---------+
| product_id | product_name | balance |
+------------+--------------+---------+
| 111 | Product One | 9 |
| 222 | Product Two | 9 |
| 333 | Product Three| 2 |
| 444 | Product Four | 6 |
+------------+--------------+---------+
最後に、このソリューションの実用的なSQLを取得しましたが、これがこれを行う最良の方法であるかどうかはわかりません. これらのテーブルには大量のレコードがあるため、パフォーマンスが非常に心配です。
SELECT p.product_id,p.product_name,
IFNULL(sum(st.qty_received),0)+IFNULL(sold,0) as balance FROM products p
LEFT JOIN stock st ON (p.product_id=st.product_id)
LEFT JOIN (SELECT sa.product_id,sum(sa.qty_sold) as sold FROM sales sa
GROUP BY sa.product_id) as t1 ON (t1.product_id=p.product_id)
GROUP BY product_id
ストックバランスを取得するための速度/パフォーマンスを向上させるために、誰でもより良いSQL(またはスキーマの変更)を提案できますか?