【问题标题】:In MYSQL, querying names of products stored in 5 warehouses that has SUM quantity > 100 for each product在MYSQL中,查询存储在5个仓库中每个产品的SUM数量> 100的产品名称
【发布时间】:2025-12-05 22:25:01
【问题描述】:

请帮我使用mysql进行查询,显示所有5个仓库中总数量SUM(goods.quantity) > 100的产品(product.name),指定数量最多的仓库(warehouse.name)每个产品的。以下是所有表格的示意图,以便更好地理解:

image of warehouses database

我正在尝试这个查询:

SELECT product.name AS product, warehouse.name AS warehouse 
FROM product, warehouse, goods 
WHERE goods.productId = product.id AND goods.warehouseId = warehouse.id 
GROUP BY product.name, warehouse.name 
HAVING SUM(goods.quantity)>100;

它给了我以下信息:

product warehouse
engine New York
right back door New York
main frame London
left back door London
back lights London
steering wheel Sydney
wheel Toronto
car cleaner Toronto

但它只显示所有仓库中具有goods.quantity > 100 的产品,而不是SUM(goods.quantity) > 100

此外,它不显示每种产品数量最多的仓库,而是显示有该产品的任何仓库。

【问题讨论】:

  • 提供示例数据(作为 CREATE TABLE + INSERT INTO 脚本)和该数据所需的输出。
  • 你使用的是什么 MySQL 版本?
  • 不相关,但是:不要使用逗号分隔的连接。请改用INNER JOIN, LEFT OUTER JOIN 等。这些显式连接是 1992 年在标准 SQL 中引入的。那是在 MySQL 出现之前。我的建议:放弃教你这种古老语法的老师、书籍或教程。
  • 您查询的主要问题是您按产品和仓库分组。这意味着您是商品行的级别之一,SUM(quantity)quantity 相同。您想查看一种产品,即按产品分组。
  • 对,但是当我只按 product.name 分组时,它给我一个错误 ERROR 1055 (42000): Expression #3 of SELECT list is not in GROUP BY, 所以它需要按warehouse.name 分组也是。

标签: mysql sql


【解决方案1】:

尝试在所选字段中添加SUM(goods.quantity) 以显示该号码 你也可以ORDER BY SUM(goods.quantity) DESC,所以最高数量在顶部。

SELECT product.name AS product, warehouse.name AS warehouse, SUM(goods.quantity) FROM product, warehouse, goods WHERE goods.productId = product.id AND goods.warehouseId = warehouse.id GROUP BY product.name, warehouse.name HAVING SUM(goods.quantity)>100;

【讨论】:

  • 谢谢,但它仍然给出相同的结果,只是再添加一列 SUM(商品数量) - 该列不应该在所选字段中。它仍然没有显示数量最多的仓库,也没有显示每个仓库中商品数量 100的产品。
【解决方案2】:

您可以尝试使用您的查询作为子查询结果来计算仓库的数量

    select products 
    from  (
        SELECT product.name AS product, warehouse.name AS warehouse 
        FROM product
        INNER JOIN warehouse  goods.warehouseId = warehouse.id 
        INNER JOIN  goods goods.productId = product.id AND
        WHERE goods.productId = product.id AND goods.warehouseId = warehouse.id 
        GROUP BY product.name, warehouse.name 
        HAVING SUM(goods.quantity)>100;

    ) t 
    group by products
    having count(distinct warehouse) = 5

【讨论】:

    【解决方案3】:

    您必须逐步完成此操作。首先,您需要每个产品的总数量和最大数量。这样你就可以决定是否展示这个产品,然后展示什么仓库。这意味着首先是聚合,然后是一些连接。

    最后你必须准备好有关系(每个产品的最大数量相同的两个仓库)。您可以使用GROUP_CONCAT 获取*仓库列表。

    select 
      p.id,
      p.name as product_name,
      group_concat(w.name) as warehouse_names
    from
    (
      select 
        productid, 
        max(quantity) as max_qantity
      from goods
      group by productid
      having sum(quantity) > 100
    ) base
    join product p on p.id = base.productid
    join goods g on g.productid = base.productid and p.quantity = base.max_qantity
    join warehouse w on w.id = g.warehouseid
    group by p.id
    order by product_name;
    

    【讨论】:

    • 非常感谢!这个很好用,我刚试过。虽然,这远远超出了我对 SQL 的理解,但我无法完全理解你写的内容:(
    • 先看基本子查询。每个产品我采取最大数量。但是我只取总数> 100的产品。你可以单独运行这个来看看它的结果。现在,对于这个结果,我加入产品表以获取产品名称。然后我再次加入货物,因为这样我找到了该产品数量的仓库。然后我加入仓库表以获取仓库名称。最后我再次聚合,因为当两个仓库的最高数量相同时,我可能有两行产品。因此,再次按产品分组以获得每个产品的一个结果行。