This is a bit more than I had hoped, but this solution works.
Basically, I use CTE (Common Table Expression), which splits the table and traverses all the values ββfrom the <FID> nodes in the basket names.
From this CTE, I select those baskets that contain both a value of 1 or 3 .
DECLARE @Test TABLE (BasketID INT, BasketName VARCHAR(20), BasketFruits XML) INSERT INTO @TEST VALUES(1, 'Gold', '<FRUITS><FID>1</FID><FID>2</FID><FID>3</FID><FID>4</FID><FID>5</FID><FID>6</FID></FRUITS>'), (2, 'Silver', '<FRUITS><FID>1</FID><FID>2</FID><FID>3</FID><FID>4</FID></FRUITS>'), (3, 'Bronze', '<FRUITS><FID>3</FID><FID>4</FID><FID>5</FID></FRUITS>') ;WITH IDandFID AS ( SELECT t.BasketID, t.BasketName, FR.FID.value('(.)[1]', 'int') AS 'FID' FROM @Test t CROSS APPLY basketfruits.nodes('/FRUITS/FID') AS FR(FID) ) SELECT DISTINCT BasketName FROM IDandFID i1 WHERE EXISTS(SELECT * FROM IDandFID i2 WHERE i1.BasketID = i2.BasketID AND i2.FID = 1) AND EXISTS(SELECT * FROM IDandFID i3 WHERE i1.BasketID = i3.BasketID AND i3.FID = 3)
By running this query, I get the expected output:
BasketName ---------- Gold Silver
source share