【问题标题】:TSQL: Join tables based on criteriaTSQL:根据条件连接表
【发布时间】:2018-12-23 20:53:29
【问题描述】:

我打算收到的结果集是这样的:

我的表结构是这样的:

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

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

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

如果我跑了

SELECT * 
FROM STOCK 
WHERE STOCKCODE = 'XYZ'

我得到 152 个结果。所以我有 152 种产品,STOCKCODE 肯定是 'XYZ'..

我的问题是当我尝试加入这些表时。为简单起见,我只尝试让INVTYPE 101 保持简单,但我想要的结果仍然是 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 个结果。所以我知道 stock 表中有 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

所以我的问题是如何实现我想要的结果集?我的加入有什么问题?

谢谢

【问题讨论】:

  • 您能提供一些示例数据并期待结果吗?

标签: sql sql-server tsql


【解决方案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】:

    由于您没有将内部表 (INVOICE_ITEM) 与它们的主键连接起来,因此这是一种预期行为。

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

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

    【讨论】:

      【解决方案3】:

      为了性能,尝试一下是很有诱惑力的:

      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'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-11-01
        • 2023-03-06
        • 2021-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多