2013-04-05 77 views
1

似乎无法让我的头在此。我有三个表格(股票,销售,采购订单)与产品有关的一个共同的领域,可以加入他们所有。我有第四张桌子,里面放着所有的产品。产品可能有或没有这些表中的信息(库存,销售,采购订单),但在产品表中会有记录。SQL;全左,右,上,内,反向连接

我需要结束一行每个产品,其中有三个表(股票,销售和采购订单)之一的信息。

表的简化视图低于:

产品表,参考,描述

库存表,REF Current_Stock

销售表,REF Qty_Sold

采购单表,Re女,Qty_Outstanding

我需要与下列结束:

参考,描述Current_Stock,Qty_Sold,Qty_Outstanding

由于

尼格

+1

您使用的是什么RDBMS。是否在所有4个表中都提供了唯一的产品ID? – 2013-04-05 11:26:19

回答

1

也许,这样做的最简单,最直接的方法是将左加入所有细节表到Product表,然后筛选出具有没有匹配的所有产品。

所以,这将基本上@ Santhosh的一个小调整溶液(强调):

SELECT 
    pr.Ref, 
    pr.Description, 
    st.Current_Stock, 
    sa.Qty_Sold, 
    po.Qty_Outstanding 
FROM Product pr 
LEFT JOIN Stock st ON st.Ref = pr.Ref 
LEFT JOIN Sales sa ON sa.Ref = pr.Ref 
LEFT JOIN POs po ON po.Ref = pr.Ref 
WHERE st.Ref IS NOT NULL OR sa.Ref IS NOT NULL OR so.Ref IS NOT NULL 
; 

还有一个不那么明显的替代:工会的所有详细信息表,然后转动详细数据。结果集仅包含对至少包含一些详细信息的产品的引用。因此,您可以将结果集内部加入Product以访问输出的产品说明。

如果你的SQL产品支持PIVOT子句中,你可以做这样的:

SELECT 
    p.Ref, 
    p.Description, 
    s.Current_Stock, 
    s.Qty_Sold, 
    s.Qty_Outstanding 
FROM (
    SELECT 
    Ref, 
    Current_Stock, 
    Qty_Sold, 
    Qty_Outstanding 
    FROM (
    SELECT 
     Ref, 
     'Current_Stock' AS Attribute, 
     Current_Stock AS Value 
    FROM Stock 
    UNION ALL 
    SELECT 
     Ref, 
     'Qty_Sold', 
     Qty_Sold 
    FROM Sales 
    UNION ALL 
    SELECT 
     Ref, 
     'Qty_Outstanding', 
     Qty_Outstanding 
    FROM POs 
) d 
    PIVOT (
    SUM(Value) FOR Attribute IN (
     Current_Stock, 
     Qty_Sold, 
     Qty_Outstanding 
    ) 
) p 
) s 
INNER JOIN Product p ON p.Ref = s.Ref 
;

还有回转的老年人和更普遍的方法,为此,你需要使用分组和有条件聚集:

SELECT 
    p.Ref, 
    p.Description, 
    SUM(CASE Attribute WHEN 'Current_Stock' THEN d.Value END) AS Current_Stock, 
    SUM(CASE Attribute WHEN 'Qty_Sold'  THEN d.Value END) AS Qty_Sold, 
    SUM(CASE Attribute WHEN 'Qty_Outstanding' THEN d.Value END) AS Qty_Outstanding 
FROM (
    SELECT 
    Ref, 
    'Current_Stock' AS Attribute, 
    Current_Stock AS Value 
    FROM Stock 
    UNION ALL 
    SELECT 
    Ref, 
    'Qty_Sold', 
    Qty_Sold 
    FROM Sales 
    UNION ALL 
    SELECT 
    Ref, 
    'Qty_Outstanding', 
    Qty_Outstanding 
    FROM POs 
) d 
INNER JOIN Product p ON p.Ref = d.Ref 
GROUP BY 
    p.Ref, 
    p.Description 
;
+0

谢谢Andriy,我选择使用左连接和where子句 – nig 2013-04-06 13:29:22

0
SELECT P.REF, P.DESCRIPTION, S.CURRENT_STOCK, SALES.QTY_SL, POS.QTY_OUTSTANDING 
FROM PRODUCTS P 
LEFT JOIN STOCK S 
ON S.REF = P.REF 
LEFT JOIN SALES SALES 
ON SALES.REF = P.REF 
LEFT JOIN POS 
ON POS.REF = P.REF 
+0

使用左外部联接会给我产品表中所有关于我是否在其他表中有记录的所有信息。我想忽略三个表格(股票,销售,采购订单)中没有任何相关记录的产品。也许我需要一个WHERE子句? – nig 2013-04-05 11:39:10

+0

在查询中使用内部联接而不是左侧关键字。 – Santhosh 2013-04-05 12:16:14

+0

不幸的是INNER JOIN's只会返回每张表有每个参考数据的记录:http://sqlfiddle.com/#!6/05768/5 – nig 2013-04-05 16:10:30

0

假设REF独特并且使用像外键所有表

中也许你可以试试

SELECT pt.REF, pt.DESCRIPTION, st.CURRENT_STOCK, sat.QTY_SOLD, pot.QTY_OUTSTANDING 
FROM PRODUCTTABLE pt 
INNER JOIN STOCKTABLE st 
ON st.REF = pt.REF 
INNER JOIN SALESTABLE sat 
ON sat.REF = pt.REF 
INNER JOIN POSTABLE pot 
ON pot.REF = pt.REF 

我只是喜欢这个Graphical summary of join operations非常有用的!

+0

使用内部联接只会让我回到三个表(股票,销售,采购订单)都有一个外键的地方。 (顺便说一下,很好的链接) – nig 2013-04-05 11:36:56

+0

产品表中有多少行?与不同的REF? – bAN 2013-04-05 11:39:16

+0

产品表中大约有50万行。 – nig 2013-04-05 11:51:06