Вы можете создать ключ для каждой группы и присоединиться к нему.
В вашем примере ключ Apple_1_Banana_1_Carrot_2_
создаст для order_ref = "A1" доставки и invoice_num = "500" счета.
DECLARE @shipping TABLE (shipping_id INT, order_ref VARCHAR(10), product VARCHAR(10), quantity INT)
INSERT INTO @shipping VALUES
(100 , 'A1', 'Apple', 1),
(101 , 'A1', 'Banana', 1),
(102 , 'A1', 'Carrot', 2)
DECLARE @invoice TABLE (invoice_num INT, line_num INT, product VARCHAR(10), quantity INT)
INSERT INTO @invoice VALUES
(500, 1 ,'Apple', 1 ),
(500, 2 ,'Banana', 1 ),
(500, 3 ,'Carrot', 2 ),
(501, 1 ,'Apple', 10 ),
(501, 2 ,'Banana', 1 ),
(501, 3 ,'Carrot', 2 )
SELECT * FROM (
SELECT * FROM @shipping s
CROSS APPLY(SELECT product + '_' + CAST(quantity AS varchar(10)) + '_'
FROM @shipping s2 WHERE s.order_ref = s2.order_ref
ORDER BY product , quantity FOR XML PATH('')) X(group_key)
) A
INNER JOIN
(SELECT * FROM @invoice i
CROSS APPLY(SELECT product + '_' + CAST(quantity AS varchar(10)) + '_'
FROM @invoice i2 WHERE i.invoice_num = i2.invoice_num
ORDER BY product , quantity FOR XML PATH('')) X(group_key)
)B ON A.group_key = B.group_key
AND A.product = B.product
AND A.quantity = B.quantity
Результат:
shipping_id order_ref product quantity line_num invoice_num line_num product quantity
----------- ---------- ---------- ----------- -------------------- ----------- ----------- ---------- -----------
100 A1 Apple 1 1 500 1 Apple 1
101 A1 Banana 1 2 500 2 Banana 1
102 A1 Carrot 2 3 500 3 Carrot 2