【问题标题】:How do I retrieve all products in inventory, but also any product available with SQL?如何检索库存中的所有产品,以及 SQL 可用的任何产品?
【发布时间】:2014-08-27 15:40:00
【问题描述】:

我需要显示特定仓库当前库存的所有产品,以及产品表中的所有产品。这将包括库存量。如果该产品未在特定仓库的库存中列出,则需要显示 0。

产品表中有 33 种不同的产品。这是我用来查找该信息的查询:

SELECT DISTINCT ID
FROM S_PRODUCT;

我正在查看的仓库专门包含 14 种产品。这是我用来查找的查询。

SELECT PRODUCT_ID
FROM S_INVENTORY
WHERE WAREHOUSE_ID = 301;

我的最终结果应该列出所有 33 个产品 ID,但只显示仓库 301 库存中物品的数量。不在该库存中的所有产品的数量都应显示为 0。我尝试过外部联接和其他杂项查询,但都没有运气。请帮忙!我应该注意我正在使用oracle。

ERD 中表的屏幕截图

尝试外连接和大小写。

SELECT I.PRODUCT_ID,
  CASE I.AMOUNT_IN_STOCK 
  WHEN NULL
  THEN 0
  ELSE I.AMOUNT_IN_STOCK
  END AS "IN_STOCK"
FROM S_PRODUCT P
LEFT OUTER JOIN
S_INVENTORY I
ON P.ID = I.PRODUCT_ID
WHERE I.WAREHOUSE_ID = 301;

PRODUCT_ID   IN_STOCK
---------- ----------
     20510         69 
     20512         28 
     30321         85 
     30421        102 
     30433         35 
     32779        102 
     32861         57 
     40421         70 
     40422         65 
     41010         59 
     41020         61 
     41050         49 
     41080         50 
     41100         42 

 14 rows selected 

尝试使用 AND 而不是 WHERE 注意:空行也是输出的一部分

PRODUCT_ID   IN_STOCK
---------- ----------









 20510         69 
 20512         28 
 30321         85 

 30421        102 

 30433         35 
 32779        102 
 32861         57 
 40421         70 
 40422         65 
 41010         59 
 41020         61 
 41050         49 
 41080         50 
 41100         42 









 33 rows selected 

【问题讨论】:

  • 如果您需要两个表中的 ALL,您不需要完全外连接吗?此外,要么将 where 子句移动到连接中,要么使用 (i.warehouse_ID = 301 OR i.warehouse_ID is null) 误读。只需将您的 where 子句移至联接。不需要 Where 子句。
  • 更新了我的答案以修复缺失的信息。查询现在返回了正确的数据,我们现在需要正确显示。

标签: sql oracle10g


【解决方案1】:

我没有对此进行测试,但我认为您的答案应该是这样的:

为 MS SQL 编写:

SELECT p.ID, CASE NVL(i.AMOUNT_IN_STOCK, '0') WHEN '0' THEN 0 ELSE i.AMOUNT_IN_STOCK END StockLevel
FROM S_PRODUCT p LEFT OUTER JOIN
     S_INVENTORY i ON p.PRODUCT_ID = i.PRODUCT_ID AND i.WAREHOUSE_ID = 301

我正在从您的产品表中选择所有产品并加入产品 ID 上的库存表,并且仅在仓库为 301 的位置。如果 Inventory 表没有返回匹配项,那么我使用 CASE 语句来显示 0 或显示实际值。

【讨论】:

  • 这正是我认为的解决方案,但不幸的是它只返回 14 行。我在上面的帖子中添加了结果。
  • 我的查询与您的不同,我没有WHERE 子句。我认为WHERE I.WAREHOUSE_ID = 301 正在取消你的LEFT OUTER JOIN 并给你一个INNER JOIN
【解决方案2】:

做什么:

SELECT P.PRODUCT_ID,
  coalesce(i.amount_in_Stock,0) AS "IN_STOCK"
FROM S_PRODUCT P
LEFT OUTER JOIN S_INVENTORY I
  ON P.ID = I.PRODUCT_ID
 AND I.WAREHOUSE_ID = 301;

返回?

--注意缺少 WHERE 子句和将 i.warehouse_ID 移动到连接。这是因为 I.warehouse ID 会从 S_PRODUCT 中消除否定左外连接的记录。因为如果 s_Inventory 中没有该产品的 301 条目,则所有 i.warehouse_ID 都将为空。因此笛卡尔生成,然后 where 消除了左连接保存的记录。通过将限制移动到过滤器的连接发生在笛卡尔之前。

【讨论】:

  • 我在上面添加了该查询的结果。
  • 更新了选择以从产品中提取而不是从库存中提取'Duh' 并非所有产品都在仓库 301 中...并使用coalese 来处理空值而不是大小写.. 因为我不确定可以这样评价。您看到的空白是因为我们需要引用 s_product 而不是 S_Inventory 作为值。
猜你喜欢
  • 2019-09-23
  • 1970-01-01
  • 1970-01-01
  • 2013-12-24
  • 1970-01-01
  • 2011-08-31
  • 1970-01-01
  • 1970-01-01
  • 2013-05-18
相关资源
最近更新 更多