I have two tables. One is the Transaction table and the other is the PriceBook table.
-Transaction Table- |ItemID | Assortment |UnitID| |-------|--------------|------| |A01 | 1 |ea | |A02 | 1 |kg | |A03 | 2 |pc | -PriceBook Table- |ItemID | Assortment |UnitID |Price| |-------|---------------|-------|-----| |A01 | 1 | ea |1.5 | |A02 | 1 | pc |2.5 | |A03 | 2 | kg |5 | |A03 | 2 | pc |1 |
I want to select the price from the PriceBook table, matching with the ItemID, Assortment and UnitID with Transaction table. But the UnitID match is optional, so if there is no match with UnitID, I want to have the matching result with only ItemID and Assortment.
-Result Table- |ItemID| UnitID| Price| |------|----------|------| |A01 | ea |1.5 | |A02 | pc |2.5 | |A03 | pc |1 |
I am using LEFT OUTER Join, but when I am matching ItemID and Assortment, I am getting two rows for Item A03 (I require only one), and if I am matching with ItemID, Assortment and UnitID, I am getting null for Item A02. Following is my query.
select DISTINCT Tx.ItemID, Pb.UnitID, Pb.Price from Transaction Tx with (nolock) LEFT OUTER JOIN PriceBook Pb With (NOLOCK) ON Tx.ItemID = Pb.ItemID AND Tx.Assortment = Pb.Assortment AND Tx.UnitID = Pb.UnitID -- (This conditional should be optional)
How do I get my desired result?
Advertisement
Answer
You may use outer apply
for rows that didn’t match by more columns:
with t(ItemID, Assortment, UnitID) as ( select 'A01', 1, 'ea' union all select 'A02', 1, 'kg' union all select 'A03', 2, 'pc' ) , pr(ItemID, Assortment, UnitID, Price) as ( select 'A01', 1, 'ea', 1.5 union all select 'A02', 1, 'pc', 2.5 union all select 'A03', 2, 'kg', 5 union all select 'A03', 2, 'pc', 1 ) select t.itemid , t.assortment , coalesce(pr.unitid, pr2.unitid, t.unitid) as unitid , coalesce(pr.price, pr2.price) as price from t left join pr on t.itemid = pr.itemid and t.assortment = pr.assortment and t.unitid = pr.unitid outer apply ( select top 1 pr2.unitid, pr2.price from pr as pr2 where t.itemid = pr2.itemid and t.assortment = pr2.assortment /*When no matches by unitid*/ and pr.itemid is null ) as pr2
itemid | assortment | unitid | price :----- | ---------: | :----- | ----: A01 | 1 | ea | 1.5 A02 | 1 | pc | 2.5 A03 | 2 | pc | 1.0
db<>fiddle here