select 在同一列上使用多个条件进行查询

select query with multiple conditions on same column

我有 2 个 id 为

的主表
ingredients master
------
id int
name varchar(50)

product master
-----
id int
pname varchar(50)

product ingredients
----
inId int (fk - ingredients master)
prId int (fk - product master)

现在的情况是产品的数据低于

ingredients master ----- (id , name) {[1 , floor], [2 , salt], [3 , sugar], [4 , oil], [5 , pepper]}

product master ----- (id , pname) {[1 , chapati], [2 , pizza bun], [3 , chappati type 2], [4 , pizza bun type 2]}

product ingredients ----- (inId , prId) {[1, 1], [2, 1], [3, 1], [1, 2], [2, 2], [3, 2], [4, 2], [1, 3], [2, 3], [3, 3], [1, 4], [2, 4], [3, 4], [4, 4]}

现在我想发起一个 select 查询,在那里我可以获得 2 型薄煎饼作为薄煎饼的替代品或 2 型披萨面包作为披萨面包的替代品

我已经尝试了 google 很多,但无法提出可行的解决方案。

我只想要与给定项目完全相同的替代项目。像 chapati 和 chapati type 2 在成分方面完全相同。披萨面包和披萨面包类型 2 完全相同,但是当我尝试查询时,它会提供所有项目。因为有些东西,比如地板,都是通用的。

如果我理解你的问题,你可以使用此查询来获取薄煎饼和披萨面包类型 2(常见)的成分:

select ingredients.id
from ingredients master join product master join product ingredients (complete it)
where product.name in ('chapati', 'pizza bun type 2')
group by ingredients.id
having count(*)>1

然后你可以找到具有相似成分的产品

select product.name
from ingredients master join product master join product ingredients (complete it)
where ingredients.id in (first query)

当两种产品的成分相同时,它被视为替代产品。每个产品都有多种成分 - 多行。比较跨行的值很困难。如果每个产品只有 1 种成分 - 将多行合并为 1 个值,则更容易识别哪些产品具有相同的成分。

CREATE TABLE #IngredientsMaster
(IngredientId INT
,IngredientName VARCHAR(50)
);
CREATE TABLE #ProductMaster
(ProductId INT
, ProductName VARCHAR(50)
);
CREATE TABLE #ProductIngredients
(IngredientId INT 
,ProductId INT
);
INSERT #IngredientsMaster
VALUES(1 , 'floor'), (2 , 'salt'), (3 , 'sugar'), (4 , 'oil'), (5 , 'pepper');

INSERT #ProductMaster
VALUES(1 , 'chapati'), (2 , 'pizza bun'), (3 , 'chappati type 2'), (4 , 'pizza bun type 2');

INSERT #ProductIngredients  
VALUES (1, 1), (2, 1), (3, 1), (1, 2), (2, 2), (3, 2), (4, 2), (1, 3), (2, 3), (3, 3), (1, 4), (2, 4), (3, 4), (4, 4)

;WITH cte AS (SELECT pg.ProductId, Productname
                , STUFF((SELECT '-' + cast(t.IngredientId AS VARCHAR(3)) 
                FROM #ProductIngredients t
                WHERE t.productId = pg.productId
                ORDER BY t.ingredientId
                FOR XML PATH('')
                ), 1, 1, '') AS Ingredients
FROM #ProductIngredients pg
INNER JOIN #IngredientsMaster i
ON i.IngredientId = pg.IngredientId
INNER JOIN #ProductMaster p
ON p.ProductId = pg.ProductId
GROUP BY pg.ProductId, Productname
)
SELECT *
FROM cte cte
WHERE EXISTS (SELECT * FROM cte t WHERE t.Ingredients = cte.Ingredients AND t.ProductId = 2);