Это немного сложнее, чем я надеялся, но это решение работает.
По сути, я использую CTE (Common Table Expression), который разбивает таблицу и перекрестно соединяет все значения от узлов <FID>
с именами корзин.
Из этого CTE я выбираю те корзины, которые содержат значения 1
и 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)
Запустив этот запрос, я получаю ожидаемый результат:
BasketName
----------
Gold
Silver