TSQL-记录子集上的精确匹配
我有下表的结构和数据TSQL-记录子集上的精确匹配,sql,sql-server,tsql,Sql,Sql Server,Tsql,我有下表的结构和数据 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
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
我想做的是能够识别那些具有精确匹配的发票记录组的信用记录。精确匹配指的是相同的产品、OrderRef、数量和日期
在上述数据中,C123将与Inv111匹配,但C999将与Inv666不匹配,因为Inv666缺少一行
我想删除完全匹配的信用记录和发票记录。除了OrderRef之外,发票和信用证之间没有链接
我一直在玩弄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
)
这给了我表a中的所有内容,而不是我所期望的表b中的所有内容
问题是我真的需要TransactionID,这样我才能继续正确地删除
这句话的意思是错误的吗?我可以使用合并吗?如果我读对了,像这样的东西应该可以用
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
)
试试这个,以获得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
我认为
左连接
和一些组
ing是处理此要求的最明显的方法:
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中并执行unpivot。生成的TransID应该是需要删除的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
我假设如果发票与信用证之间有额外的一行,您也不想声明匹配?这样的数据可能存在吗?对不起,我应该指定。如果有额外的发票行,我不会大惊小怪的。只要发票涵盖了信用,发票是否有更多的争议就无关紧要。当我将其标记为答案时,您删除了您的帖子?我不相信它涵盖了100%的角落案例,但我不确定您的数据中是否存在此类角落。我想再考虑一下这个问题。达米恩,出于好奇,如果我想更进一步,说是的-发票行必须与信用行的计数相匹配,这很重要,我该如何调整?哦,但是你需要每个TransID的所有行都匹配。。。这个不行。