我旨在接收的结果集是:
我的表结构如下:
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
所以我的问题是如何获得所需的结果集?我的联接在做什么呢?
谢谢
答案 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'