2014-08-27 114 views
1

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

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

SELECT DISTINCT ID 
FROM S_PRODUCT; 

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

SELECT PRODUCT_ID 
FROM S_INVENTORY 
WHERE WAREHOUSE_ID = 301; 

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

Screenshot of the tables in the 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 
+1

如果你需要两个表中的ALL,你不需要一个完整的外连接吗?另外,或者将where子句移动到连接或使用或者'(i.warehouse_ID = 301或者i.warehouse_ID为空)'Misread。只需将您的where子句移动到联接。否子句需要。 – xQbert 2014-08-27 16:13:01

+1

更新了我的答案以解决缺少的信息。查询现在返回正确的数据,我们现在只需要正确显示。 – 2014-08-27 16:59:23

回答

1

是什么:

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中的记录否定左外部联接。因为如果该产品的301中没有s_Inventory条目,则所有i.warehouse_ID都将为空。因此,cartesean生成,然后在那里消除左连接保存的记录。通过移动限制来加入过滤器发生在cartesean之前。

+0

我在上面添加了该查询的结果。 – billabrian6 2014-08-27 16:34:16

+1

更新选择拉从产品,而不是库存'杜'不是所有的产品都在仓库301 ...并使用coalese来处理空值,而不是案件..因为我不是不确定null可以这种方式进行评估。你看到的空白是因为我们需要引用s_product而不是S_Inventory来获取值。 – xQbert 2014-08-27 17:17:40

+0

这工作完美!非常感谢您的帮助。 – billabrian6 2014-08-27 21:29:42

2

我没有测试过这一点,但我认为你的回答应该读的东西是这样的:

书面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的地方。如果库存表没有返回匹配项,则我使用CASE语句显示0或它显示实际值。

+0

这正是我认为的解决方案,但不幸的是它只返回14行。我在上面的帖子中添加了结果。 – billabrian6 2014-08-27 16:07:05

+3

我的查询与您的查询不同,我没有'WHERE'子句。我认为'WHERE I.WAREHOUSE_ID = 301'取消了你的'LEFT OUTER JOIN'并给你一个'INNER JOIN'。 – 2014-08-27 16:17:49