TSQL:根据条件联接表

时间:2018-12-23 10:31:48

标签: sql sql-server tsql

我旨在接收的结果集是:

required resultset

我的表结构如下:

table structure

INVOICE表具有INVTYPE列,该列通过持有101待售和201待售来定义发票是销售发票还是购买发票。

我的查询将使用where语句还将STOCK表过滤到特定的STOCKCODE

我正在尝试使用STOCK过滤产品(STOCKCODE = "XYZ"

如果我运行

SELECT * 
FROM STOCK 
WHERE STOCKCODE = 'XYZ'

我得到152个结果。因此,我肯定有152个产品的STOCKCODE为“ XYZ”。

我的问题是当我尝试加入这些表时。为简单起见,我仅尝试使INVTYPE保持简单,但我希望得到的结果仍然是201。

我尝试了联接和子查询,例如:

SELECT 
    S.STOCKNO, S.STOCKNAME, ISNULL(SUM(IIT.QTYSOLD), 0) AS QTY, 
    ISNULL(SUM(IIT.TOTAL), 0) AS TOTAL 
FROM 
    STOCK S
LEFT JOIN 
    INVOICE_ITEM IIT ON S.STOCKID = IIT.STOCKID
LEFT JOIN 
    INVOICE INV ON IIT.INVID = INV.INVID
WHERE 
    S.STOCKCODE = 'XYZ' AND INV.TRANSTYPE = 101
GROUP BY 
    S.STOCKNO, S.STOCKNAME

此查询返回122个结果。因此,我知道库存表中有30件商品尚未售出,我需要在结果集中的相关列中将其显示为0(零)。

我也尝试过:

SELECT 
    S.STOCKNO, S.STOCKNAME, 
    (SELECT ISNULL(SUM(TOTAL), 0) 
     FROM INVOICE_ITEM IIT 
     WHERE IIT.STOCKID = S.STOCKID) AS TOTAL,
    (SELECT ISNULL(SUM(QTYSOLD), 0) 
     FROM INVOICE_ITEM IIT 
     WHERE IIT.STOCKID = S.STOCKID) AS QTY
FROM 
    STOCK S 
WHERE 
    S.STOCKCODE = 'XYZ'

此查询返回完整的152条结果,因为我没有按INVTYPE进行过滤,它也返回了已购买的商品。

我正在使用SQL Server 2014

所以我的问题是如何获得所需的结果集?我的联接在做什么呢?

谢谢

3 个答案:

答案 0 :(得分:1)

由于您未使用内部表(INVOICE_ITEM)的主键进行联接,因此这是预期的行为。

您要么需要使用INVITEMID列进行联接,要么需要一起添加STOCKID和INVID。

 SELECT ISNULL(SUM(TOTAL),0) FROM INVOICE_ITEM IIT 
 WHERE IIT.STOCKID = S.STOCKID and IIT.INVID = INV.INVID

答案 1 :(得分:1)

您需要条件聚合

SELECT S.STOCKNO, 
       S.STOCKNAME, 
       ISNULL(SUM(CASE WHEN INV.TRANSTYPE = 201 THEN IIT.TOTAL END), 0) AS TOTAL_PURCHASED,
       ISNULL(SUM(CASE WHEN INV.TRANSTYPE = 101 THEN IIT.TOTAL END), 0) AS TOTAL_SOLD,
       ISNULL(SUM(CASE WHEN INV.TRANSTYPE = 201 THEN IIT.QTYSOLD END),0) AS QTY_PURCHASED, 
       ISNULL(SUM(CASE WHEN INV.TRANSTYPE = 101 THEN IIT.QTYSOLD END),0) AS QTY_SOLD 
FROM STOCK S
LEFT JOIN INVOICE_ITEM IIT ON S.STOCKID = IIT.STOCKID
LEFT JOIN INVOICE INV ON IIT.INVID= INV.INVID
WHERE S.STOCKCODE= 'XYZ'
GROUP BY S.STOCKNO, S.STOCKNAME

答案 2 :(得分:1)

为了提高性能,尝试尝试:

select s.stockno, s.stockname,
       coalesce(i.total_purchased, 0) as total_purchased,
       coalesce(i.total_sold, 0) as total_sold,
       coalesce(i.qty_purchased, 0) as qty_purchased,
       coalesce(i.qty_sold, 0) as qty_sold
from stock s outer apply
     (select sum(case when i.transtype = 201 then ii.total end) as total_purchased,
             sum(case when i.transtype = 101 then ii.total end) as total_sold,
             sum(case when i.transtype = 201 then ii.qtysold end) as qty_purchased,
             sum(case when i.transtype = 101 then ii.qtysold end) as qty_sold             
      from invoice_item ii join
           invoice i
           on ii.invid = i.invid
      where s.stockid = ii.stockid
     ) i
where stockcode = 'XYZ'