Interview question
Find products matching every selected tag
Solves a many-to-many all-match filter with grouping and a deliberate empty-selection rule.
TL;DR
Solves a many-to-many all-match filter with grouping and a deliberate empty-selection rule.
Many-to-many filtering, relational division, GROUP BY, HAVING, duplicate input handling, and empty-filter behavior.
Practice the problem like a real interview: restate, reason, implement, and test.
Tables: Products(ProductId, Name, IsActive) and ProductTags(ProductId, TagId). The table-valued parameter @SelectedTags(TagId) may contain zero or more rows. Return a product only when all distinct selected tags are attached to it. An empty selection returns every active product.
Selected tags are 2 and 5. Product A has tags 2, 5, and 8, so it matches. Product B has only tag 2, so it does not. With no selected tags, both active products match.
I first count distinct requested tags. For a non-empty selection, I join product-tag rows to the selected ids, group them by product, and require the number of distinct matches to equal the requested count. The outer EXISTS keeps the product result to one row. The separate zero-count branch implements the product decision that no filter means all active products.
DECLARE @SelectedCount int =
(
SELECT COUNT(DISTINCT TagId)
FROM @SelectedTags
);
SELECT p.ProductId, p.Name
FROM dbo.Products AS p
WHERE p.IsActive = 1
AND
(
@SelectedCount = 0
OR EXISTS
(
SELECT 1
FROM dbo.ProductTags AS pt
INNER JOIN @SelectedTags AS st ON st.TagId = pt.TagId
WHERE pt.ProductId = p.ProductId
GROUP BY pt.ProductId
HAVING COUNT(DISTINCT pt.TagId) = @SelectedCount
)
)
ORDER BY p.ProductId;
A unique index on ProductTags(ProductId, TagId) protects the model and supports each product probe. For large selections or catalogs, the optimizer may prefer starting from selected tags and grouping matching product ids before joining products.
@SelectedTags.IN and returning products that match any selected tag.Move to the linked follow-up, next path step, prerequisite, or deeper variant.
Practice the next layer of the same subject.