尝试了解有关子查询的更多信息。我正在寻找一种方法来减去和比较两个表。
我的数据记录如下:
广告:
mysql> select store_id, product_id, sum(quantity) as inventory from inventories where store_id = 1 group by product_id;
+----------+------------+-----------+
| store_id | product_id | inventory |
+----------+------------+-----------+
| 1 | 8 | 24 |
| 1 | 10 | 4 |
| 1 | 14 | 24 |
+----------+------------+-----------+
3 rows in set (0.00 sec)
销售
mysql> select store_id, product_id, sum(quantity) as sales from sales where store_id = 1 group by product_id;
+----------+------------+-------+
| store_id | product_id | sales |
+----------+------------+-------+
| 1 | 8 | 12 |
| 1 | 14 | 2 |
| 1 | 8 | 1 |
+----------+------------+-------+
2 rows in set (0.00 sec)
具有以下结果的正确子查询是什么?
+----------+------------+-----------+-------+-----------+
| store_id | product_id | inventory | sales | remaining |
+----------+------------+-----------+-------+-----------+
| 1 | 8 | 24 | 12 | 12 |
| 1 | 14 | 24 | 2 | 22 |
| 1 | 8 | 12 | 1 | 11 |
+----------+------------+-----------+-------+-----------+
答案 0 :(得分:3)
要获得所需的输出,您需要计算产品销售的总计。要获得有意义的数据,sales
表中的数据必须按时间顺序排序。因此,您至少需要一个字段来对数据进行排序 - 无论是时间戳还是id
字段都无关紧要。假设销售表中有id
字段。这是一个获得您所描述内容的查询:
SELECT
sales.id,
sales.store_id,
sales.product_id,
inventories.quantity-IFNULL(SUM(sales_2.quantity), 0) as inventory,
sales.quantity as sales,
inventories.quantity-IFNULL(SUM(sales_2.quantity), 0) - sales.quantity as remaining
FROM
sales
INNER JOIN
inventories ON inventories.store_id = sales.store_id
AND inventories.product_id = sales.product_id
LEFT JOIN
sales AS sales_2 ON sales_2.store_id = sales.store_id
AND sales_2.product_id = sales.product_id
AND sales_2.id < sales.id
GROUP BY sales.id , sales.store_id , sales.product_id
ORDER BY sales.id
名为sales
的{{1}}表的第二个实例用于计算早期销售额的总和(sales_2
)
您可以从sales_2.id<sales.id
子句中排除sales.id
,但您需要将其保留在select
和group by
中。
答案 1 :(得分:3)
您可以使用查询中的结果并加入它们来计算每种产品的剩余数量
SELECT
a.store_id,
a.product_id,
a.inventory,
b.sales,
a.inventory - b.sales AS remaining
FROM (
SELECT store_id, product_id, COALESCE(SUM(quantity),0) AS inventory
FROM inventories WHERE store_id = 1
GROUP BY product_id) a
LEFT JOIN (
SELECT store_id, product_id, COALESCE(SUM(quantity),0) AS sales
FROM sales WHERE store_id = 1
GROUP BY product_id ) b USING(store_id, product_id)
答案 2 :(得分:2)
尝试将两个表连接为:
SELECT I.store_id, I.product_id, I.inventory, S.sales, (I.inventory - S.sales) AS remaining
FROM Sales S INNER JOIN INVENTOR I
ON I.store_id = S.store_id
AND I.product_id = S.product_id
答案 3 :(得分:1)
我发布了一个答案,然后重新阅读了你想要的内容。我意识到我读错了东西,我发现你确实希望将销售视为按顺序扣除的个别交易,即&#34;历史&#34;。您仍然需要某种交易ID或交易日期来确定它们应用于哪个订单。在另一个答案中也已经注明了这一点。也许你想依赖MySQL行id或其他东西。我对MySQL没有足够的了解,可以帮助你解决这个问题。
select
i.store_id, i.product_id,
i.inventory - s.previous_sales as inventory,
s.quantity as sales,
i.inventory - s.previous_sales - s.quantity as remaining
from
inventories as i inner join
(
select store_id, product_id, quantity,
(
select sum(quantity)
from sales as s2
where
s2.store_id = s.store_id and s2.product_id = s.product_id
/* all sales for this store and product prior to this one */
and s2.[sequencing column] < s.[sequencing column]
) as previous_sales
from sales
group by store_id, product_id
) as s
on s.store_id = i.store_id and s.product_id = i.product_id
where
i.store_id = 1
我不知道您将如何处理广告资源中的更改或者需要从广告资源中扣除的销售回溯量。这可以在您编写时解决问题。
答案 4 :(得分:1)
样本数据非常有限,但我相信我们可以做出这些假设。
如果没有必要聚合库存,那么您可以使用单个&#34;派生表&#34;,这是一种子查询,如下所示:
SELECT
I.store_id
, I.product_id
, COALESCE(I.inventory, 0) AS INVENTORY
, COALESCE(S.sales, 0) AS SALES
, COALESCE(I.inventory, 0) - COALESCE(S.sales, 0) AS REMAINING
FROM Inventory I
LEFT JOIN (
SELECT
store_id
, product_id
, SUM(sales) AS SALES
FROM Sales
WHERE store_id = 1
GROUP BY
product_id
) S ON I.store_id = S.store_id
AND I.product_id = S.product_id
WHERE I.store_id = 1
ORDER BY
I.store_id
, I.product_id
;
如果还需要汇总库存,您可以使用2&#34;派生表&#34;像这样:
SELECT
I.store_id
, I.product_id
, COALESCE(I.inventory, 0) AS INVENTORY
, COALESCE(S.sales, 0) AS SALES
, COALESCE(I.inventory, 0) - COALESCE(S.sales, 0) AS REMAINING
FROM (
SELECT
store_id
, product_id
, SUM(inventory) AS INVENTORY
FROM Inventory
WHERE store_id = 1
GROUP BY
product_id
) I
LEFT JOIN (
SELECT
store_id
, product_id
, SUM(sales) AS SALES
FROM Sales
WHERE store_id = 1
GROUP BY
product_id
) S ON I.store_id = S.store_id
AND I.product_id = S.product_id
ORDER BY
I.store_id
, I.product_id
;
或者您可以使用&#34;相关子查询&#34;在select子句中,如下所示:
SELECT
I.store_id
, I.product_id
, COALESCE((
SELECT
SUM(sales)
FROM sales S
WHERE S.store_id = I.store_id
AND S.product_id = I.product_id
), 0) AS SALES
, I.inventory - COALESCE((
SELECT
SUM(sales)
FROM sales S
WHERE S.store_id = I.store_id
AND S.product_id = I.product_id
), 0) AS REMAINING
FROM Inventory AS I
WHERE I.store_id = 1
ORDER BY
I.store_id
, I.product_id
;
您已经问过哪个是&#34;正确的子查询&#34;。我相信以上所有语法都是正确的,但是&#34;正确的&#34;我不完全明白。如果你的意思是哪个会表现最好,我会建议派生表优先于相关子查询,但要得出适用于所有情况的答案几乎是不可能的。
要评估最佳性能需要更好地定义数据,表和索引,强烈建议使用执行计划。也可能是不使用任何子查询是最好的方法(即连接)。
在此处查看上述查询作为示例:http://sqlfiddle.com/#!9/fa6b6/1
答案 5 :(得分:1)
理想的子查询将是使用表格键的子查询。
对于您的库存表,您应该有一个PRIMARY KEY(store_id,product_id)。
ALTER TABLE inventories ADD PRIMARY KEY (store_id, product_id).
如果这不是唯一的(在这种情况下,它实际上不是库存,而是“传入项目”表),您可以为这两列设置INDEX。
ALTER TABLE inventories ADD INDEX (store_id, product_id).
您必须在销售表中定义相同的索引
ALTER TABLE sales ADD INDEX (store_id, product_id).
在定义这些键之后,我们可以知道设置完美和长效的子查询。
SQL:
SELECT t1.store_id, t1.product_id, t1.quantity inventory,
IFNULL(sum(t2.quantity), 0) sales,
t1.quantity-IFNULL(sum(t2.quantity), 0) remaining
FROM inventories t1
LEFT JOIN sales t2 ON t1.store_id=t2.store_id
AND t1.product_id=t2.product_id
WHERE t1.store_id=1
GROUP BY t1.store_id, t1.product_id;
除了查询inventories
表而不是查询SELECT store_id, product_id, SUM(quantity) quantity
FROM inventory
GROUP BY store_id, product_id;
表之外,你做了同样的事情,你将用以下子查询替换它:
SELECT t1.store_id, t1.product_id, t1.quantity inventory,
IFNULL(sum(t2.quantity), 0) sales,
t1.quantity-IFNULL(sum(t2.quantity), 0) remaining
FROM
(SELECT store_id, product_id, SUM(quantity) quantity
FROM inventory
GROUP BY store_id, product_id) t1
LEFT JOIN sales t2 ON t1.store_id=t2.store_id
AND t1.product_id=t2.product_id
WHERE t1.store_id=1
GROUP BY t1.store_id, t1.product_id;
结果将如下:
{{1}}
答案 6 :(得分:1)
假设您有一个产品表和一个商店表,然后将它们加在一起,以获得产品和商店的组合。这样,一行不依赖于您感兴趣的商店中仍在库存中的产品,或者尚未从您感兴趣的商店销售的产品。
然后LEFT OUTER JOIN子查询以获取库存和销售或每个产品/商店。
SELECT b.store_id, a.product_id, IFNULL(c.inventory, 0), IFNULL(d.sales, 0) , (IFNULL(c.inventory, 0) - IFNULL(d.sales, 0)) AS remaining
FROM products a
INNER JOIN stores b
ON b.store_id = 1
LEFT OUTER JOIN
(
SELECT store_id, product_id, SUM(quantity) AS inventory
FROM inventories
WHERE store_id = 1
GROUP BY store_id, product_id
) c
ON a.product_id = c.product_id
AND b.store_id = c.store_id
LEFT OUTER JOIN
(
SELECT store_id, product_id, SUM(quantity) AS sales
FROM sales
WHERE store_id = 1
GROUP BY store_id, product_id
) d
ON a.product_id = d.product_id
AND b.store_id = d.store_id