我有以下表结构和数据
TransID TransType Product Qty OrderRef Date
------- --------- ------- --- -------- ----
C123 Credit Prod1 1 Order8 2014-07-08
C123 Credit Prod2 5 Order8 2014-07-08
Inv111 Invoice Prod1 1 Order8 2014-07-08
Inv111 Invoice Prod2 5 Order8 2014-07-08
C999 Credit Prod1 6 Order8 2014-07-08
C999 Credit Prod2 9 Order8 2014-07-08
Inv666 Invoice Prod1 6 Order8 2014-07-08
我想要做的是能够识别那些具有完全匹配的发票记录组的信用记录。通过完全匹配,我的意思是相同的Product,OrderRef,Qty和Date
在上面的数据中,C123会与Inv111匹配,但C999与Inv666不匹配,因为Inv666缺少一行
我想要删除具有完全匹配的Credit和Invoice记录。除了OrderRef
之外,Invoice和Credits之间没有任何关联我玩过Except语句,如下所示: -
;with CreditToInvoice(Product, Qty, OrderRef, Date)
as
(select Product
,Qty
,OrderRef
,Date)
from @t t1
where t1.TransType = 'Credit'
group by TransactionID, OrderRef, Product, Date, Qty
EXCEPT
select Product
,Qty
,OrderRef
,Date)
from @t t2
where t2.TransType = 'Invoice'
group by TransactionID, OrderRef, Product, Date, Qty
)
它给了我表格中的所有内容,而不是表格b,正如我所期待的那样
问题是我真的需要TransactionID,以便我可以继续正确删除
除此之外的错误陈述是什么?我可以使用合并吗?
非常感谢任何帮助
答案 0 :(得分:1)
我认为LEFT JOIN
和某些GROUP
是处理此要求的最明显方式:
SELECT
cr.TransID,
MAX(inv.TransID) as InvoiceID,
MAX(CASE WHEN inv.TransID is NULL THEN 1 ELSE 0 END) as Unsatsified
FROM
@t cr
left join
@t inv
on
cr.Product = inv.Product and
cr.OrderRef = inv.OrderRef and
cr.Qty = inv.Qty and
cr.Date = inv.Date and
inv.TransType = 'Invoice'
WHERE
cr.TransType = 'Credit'
GROUP BY
cr.TransID
HAVING
MAX(CASE WHEN inv.TransID is NULL THEN 1 ELSE 0 END) = 0
也就是说,我们将信用卡和发票之间的所有匹配行连接在一起,然后我们只在所有信用行达到匹配时才选择此结果。
如果您需要在单个列中同时使用TransID
个值来处理下一部分,则可以将其放在子查询或CTE中并执行取消操作。
答案 1 :(得分:1)
生成的TransID应该是您需要删除的
DECLARE @Trans TABLE
([TransID] varchar(6), [TransType] varchar(7), [Product] varchar(5), [Qty] int, [OrderRef] varchar(6), [Date] datetime)
;
INSERT INTO @Trans
([TransID], [TransType], [Product], [Qty], [OrderRef], [Date])
VALUES
('C123', 'Credit', 'Prod1', 1, 'Order8', '2014-07-08 00:00:00'),
('C123', 'Credit', 'Prod2', 5, 'Order8', '2014-07-08 00:00:00'),
('Inv111', 'Invoice', 'Prod1', 1, 'Order8', '2014-07-08 00:00:00'),
('Inv111', 'Invoice', 'Prod2', 5, 'Order8', '2014-07-08 00:00:00'),
('C999', 'Credit', 'Prod1', 6, 'Order8', '2014-07-08 00:00:00'),
('C999', 'Credit', 'Prod2', 9, 'Order8', '2014-07-08 00:00:00'),
('Inv666', 'Invoice', 'Prod1', 6, 'Order8', '2014-07-08 00:00:00')
;
DECLARE @TransUnique TABLE
([TransID] varchar(6)
)
INSERT INTO @TransUnique
SELECT DISTINCT TransID FROM @Trans
--Remove Credits
DELETE t
FROM @TransUnique t
INNER JOIN (
select t1.*,t2.TransID [TransId2],t2.TransType [TransType2]
From @Trans t1
LEFT JOIN @Trans t2 ON t1.OrderRef=t2.OrderRef
AND t1.Date=t2.Date
AND t1.Qty=t2.Qty
AND t1.Product=t2.Product
AND t2.TransType='Invoice'
WHERE t1.TransType='Credit'
) joined ON t.TransID=joined.TransId AND joined.TransId2 IS NULL
--Remove Invoices
DELETE t
FROM @TransUnique t
INNER JOIN (
select t1.*,t2.TransID [TransId2],t2.TransType [TransType2]
From @Trans t1
LEFT JOIN @Trans t2 ON t1.OrderRef=t2.OrderRef
AND t1.Date=t2.Date
AND t1.Qty=t2.Qty
AND t1.Product=t2.Product
AND t2.TransType='Invoice'
LEFT JOIN @TransUnique tu ON tu.TransID=t1.TransID
WHERE t1.TransType='Credit'
AND tu.TransID IS NULL
) joined ON t.TransID=joined.TransId2
SELECT * FROM @TransUnique
答案 2 :(得分:0)
如果我正确地读到这个,这样的事情应该有用。
select TransID, TransType, Product, Qty, OrderRef, Date from @t t1
where t1.TransType = 'Credit'
and exists (
select 1 from @t t2
where t2.TransType = 'Invoice'
and t2.Product = t1.Product
and t2.Qty = t1.Qty
and t2.OrderRef = t1.OrderRef
and t2.Date = t1.Date
)
答案 3 :(得分:0)
试试这个以获得transid
Select TransId
From @t t1
join @t t2
on t1.transtype = 'Credit' and t2.transtype = 'Invoice'
and t1.product=t2.product and t1.qty = t2.qty
and t1.orderef=t2.orderref and t1.date = t2.date