mysql - SUM() 用于相关表中的多个值

标签 mysql database-design

我在 MySQL 数据库中有三个相关表:

  • inventory_items 定义仓库中元素的类型
  • inventory_transactions 定义添加或移除的库存数量
  • 位置定义所述库存的位置

Inventory_transactions 有一个 amount_offset,用于存储在给定位置添加或删除的给定 inventory_item 的数量。

我有以下查询,它将获取 global_quantity(给定 inventory_item_id 的所有数量_offsets 的总和)以及 location_quantity,只要我知道位置 ID,它就会对特定位置执行相同的操作。

SELECT sku, name, SUM(quantity_offset) AS global_quantity,
(
SELECT SUM(quantity_offset)
    FROM inventory_transactions
    WHERE inventory_items.inventory_item_id = inventory_transactions.inventory_item_id AND inventory_transactions.location_id = 1
) AS location_quantity
FROM inventory_items
JOIN inventory_transactions ON inventory_items.inventory_item_id = inventory_transactions.inventory_item_id
GROUP BY sku

我最终想要的是为每个位置添加一列,因此结果可能具有如下值:

sku, name, global_quantity, denver_quantity, dallas_quantity, ft_wayne_quantity

我的后备方案是在单独的 inventory_item 页面上执行此操作(当我知道库存项目并可以按位置分组时),但能够在单个查询中执行此操作并将其全部放入一个表中会非常棒.

最初,我以为我可以迭代子查询,但无法以编程方式设置列名称(在 AS 中)。

预先感谢您提供的任何帮助。

最佳答案

顺便说一句,如果行来自给定位置,您可以在表达式上使用 SUM 聚合来获得相同的结果,而不是在 SELECT 列表中使用子查询,该表达式有条件地返回数量偏移量。我还会对 inventory_transactions 表使用 LEFT 外连接,这样我就可以确保为 inventory_items 中的每一行获取一行:

SELECT i.sku
     , i.name
     , SUM(t.quantity_offset) AS global_quantity
     , SUM(IF(t.location_id = 1,t.quantity_offset,NULL)) AS location_1_quantity 
  FROM inventory_items i
  LEFT
  JOIN inventory_transactions t ON i.inventory_item_id = t.inventory_item_id
  GROUP BY i.sku

(这并不能回答你的问题,但我想让你意识到这一点。)

要回答您的问题,首先,SELECT 语句不可能动态更改它在结果集中返回的列的数量或类型。您需要为要返回的每一列定义一个表达式。 (SQL SELECT 语句文本的生成可以动态完成,以生成特定的 SELECT 语句,但该 SELECT 语句返回的列由 SELECT 语句固定。)

如果我有一组相对固定的 location_id 值,并且需要您指定的结果集,我会多次重复条件表达式的 SUM,对每个位置或我想要的任何位置集重复一次:

SELECT i.sku
     , i.name
     , SUM(t.quantity_offset) AS global_quantity
     , SUM(IF(t.location_id = 1,t.quantity_offset,NULL)) AS location_1_quantity 
     , SUM(IF(t.location_id = 2,t.quantity_offset,NULL)) AS location_2_quantity 
     , SUM(IF(t.location_id = 3,t.quantity_offset,NULL)) AS location_3_quantity 
     , SUM(IF(t.location_id IN (1,2,3),t.quantity_offset,NULL)) AS location_123_quantity 
     , SUM(IF(t.location_id = 4,t.quantity_offset,NULL)) AS location_4_quantity
  FROM inventory_items i
  LEFT
  JOIN inventory_transactions t ON i.inventory_item_id = t.inventory_item_id
  GROUP BY i.sku

如果要返回的列集需要真正动态,那么我根本不会将它们作为列返回。相反,我会将每个位置的 SUM(quantity_offset) 作为单独的行返回,然后在客户端处理到按列表示的转换。

关于mysql - SUM() 用于相关表中的多个值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15032392/

相关文章:

MySQL : Count row where sum of left day is less than 30

java - MySQL:如何通过 JDBC 使用一组值来约束值对?

sql - 在 sql 中有更多或更少的表更好吗?

database - 您将如何设计数据库表来跟踪状态属性?

mysql - 如何存储嵌套位置?

mysql - 在 mysql 中查询股票/价格趋势

php - 用 CakePHP 写博客

php - 如果不需要进行查询,冗余数据是否可以?

database-design - 为无唯一 ID 的数据开发 Cassandra "schema"

java - 如何在java中执行复合sql查询?