【问题标题】:select query with multiple conditions on same column在同一列上选择具有多个条件的查询
【发布时间】:2017-07-04 12:08:37
【问题描述】:

我有 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)

现在的情况是产品有以下数据

配料大师 ----- (id , name) {[1, floor], [2, salt], [3, sugar], [4, oil], [5, pepper]}

产品大师 ----- (id , pname) {[1 , chapati], [2 , Pizza bun], [3 , chappati type 2], [4 , Pizza bun type 2]}

产品成分 ----- (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]}

现在我想触发一个选择查询,在那里我可以获得 chapati type 2 作为 chapati 的替代品或 Pizza bun type 2 作为 Pizza bun 的替代品

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

我只想要给定项目的确切替代项目。就像薄饼和薄饼类型 2 在成分方面完全相同。披萨面包和 2 型披萨面包完全相同,但是当我尝试查询时,它会给出所有项目。因为有一些像地板这样的项目是共同的。

【问题讨论】:

  • 你根本没有解释你的逻辑。您正在运行哪种查询?你有没有尝试过?
  • 我尝试了很多查询,但都返回有线结果,所以我认为最好在这里咨询专家
  • 至少告诉我们预期的输出。您想选择哪些记录?我认为LEFT JOINRIGHT JOIN 在您的情况下可能会很方便。
  • 我最近尝试的一个查询是:从 inId 所在的产品成分中选择不同的 prid(从 prId = 1 的产品成分中选择 inId),但这并没有给出任何想要的答案
  • 预期答案是这样的:如果我通过 chapati 的产品 id 即 1,那么根据当前情况,我将获得 1,3 或仅 3。或者如果我传递 chapati 类型 2 即 3 的产品 id,那么我应该只获得 1,3 或只有 1 的产品 id。因为它们都具有完全相同的成分。

标签: sql sql-server tsql select where-clause


【解决方案1】:

当两种产品成分相同时,视为替代产品。每个产品都有多种成分 - 多行。跨行比较值很困难。如果每个产品只有 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); 

【讨论】:

  • 感谢温蒂的努力。在努力思考的同时,我也想出了一个解决方案......向产品主数据添加另一个具有 varchar 数据类型的列,同时插入排序,然后将该列中的所有值插入逗号分隔或破折号分隔以及事务表中。 . 这可能很容易......
【解决方案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)

【讨论】:

  • 亲爱的 niknik,感谢您所做的努力。我只想要给定项目的替代项目。就像薄饼和薄饼类型 2 在成分方面完全相同。披萨面包和 2 型披萨面包完全相同,但是当我尝试查询时,它会给出所有项目。因为有一些像地板这样的物品在所有地方都很常见。没有达到预期的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-08
相关资源
最近更新 更多