如何请求包含MySQL中某些项的列表

时间:2013-08-21 14:22:15

标签: mysql

在我正在开发的应用程序中,用户必须设置参数来定义他将获得的最终产品。

我的表格如下:

Categories
-------------
Id   Name
1     Material
2     Color
3     Shape


Parameters
-------------
Id   CategoryId  Name
1     1           Wood
2     1           Plastic
3     1           Metal
4     2           Red
5     2           Green
6     2           Blue
7     3           Round
8     3           Square
9     3           Triangle

Combinations
-------------
Id
1
2
...

ParametersCombinations
----------------------
CombinationId  ParameterId
1               1
1               4
1               7
2               1
2               5
2               7

现在只有一些参数组合可供用户使用。在我的例子中,他可以得到一个红色圆形木制东西或绿色圆形木制东西但不是蓝色的东西,因为我无法生产它。

假设用户选择了木材和圆形参数。如何请求知道只有红色和绿色可用,所以我可以为他禁用蓝色选项? 或者有更好的方法来建模我的数据库吗?

2 个答案:

答案 0 :(得分:0)

尝试以下

SELECT p.*, pc.CombinationId
FROM Parameters p
-- get the parameter combinations for all the parameters
JOIN ParametersCombinations pc
  ON pc.ParameterId = p.Id
-- filter the parameter combinations to only combinations that include the selected parameter
JOIN (
    SELECT CombinationId
    FROM ParametersCombinations
    WHERE ParameterId = 7      -- 7 is the selected parameter
) f ON f.CombinationId = pc.CombinationId

或删除已选择的参数

SELECT p.*, pc.CombinationId
FROM Parameters p
JOIN ParametersCombinations pc
  ON pc.ParameterId = p.Id
JOIN (
    SELECT CombinationId
    FROM ParametersCombinations
    WHERE ParameterId IN (7, 1)
) f ON f.CombinationId = pc.CombinationId
WHERE ParameterId NOT IN (7, 1)

答案 1 :(得分:0)

我们假设您以下列格式提供所选参数ID

    // I call this a **parameterList** for convenience sake.
    (1,7) // this is parameter id 1 and id 7. 

我还假设您正在使用某种脚本语言来帮助您使用您的应用。像ruby或php。

我还假设您希望避免尽可能多地将逻辑存储到存储过程或MySQL查询中。

另一个假设是您使用的是快速应用程序MVC框架之一,如Rails,Symfony或CakePHP。

你的逻辑是:

  1. 找到包含parameterList中所有参数的所有组合,并将这些找到的组合放入名为relevantCombinations
  2. 的列表中
  3. 查找列表relevantCombinations中包含至少一个组合的所有parameters_combinations。仅检索唯一参数值。
  4. 前两个步骤可以使用简单的Model :: find方法和上面描述的框架中的forloop来解决。

    如果您不使用框架,那么使用原始脚本语言也很酷。

    如果在MySQL查询中需要它们,这里有一些可能的查询。请注意,这些不是最好的查询。

    第一个是

    SELECT * FROM (
      SELECT `PossibleList`.`CombinationId`, COUNT(`PossibleList`.`CombinationId`) as number
        FROM (
          SELECT `CombinationId` FROM `ParametersCombinations` 
            WHERE `ParameterId` IN (1, 7)
        ) `PossibleList` GROUP BY `PossibleList`.`CombinationId`
    ) `PossibleGroupedList` WHERE `number` = 2;
    -- note that the (1, 7) and the number 2 needs to be supplied by your app. 
    -- 2 refers to the number of parameters supplied. 
    -- In this case you supplied 1 and 7 therefore 2.
    

    要确认,请查看http://sqlfiddle.com/#!2/16831/3

    请注意我是如何故意拥有一个只有参数1而不是7的组合3.因此查询没有给你回3,但只有1和2.可以随意调整第一行的星号*。 / p>

    第二个是

    SELECT DISTINCT(`ParameterID`) 
    FROM `ParametersCombinations`
    WHERE `CombinationId` IN (1, 2);
    -- note that (1, 2) is the result we expect from the first step. 
    -- the one we call relevantCombinations
    

    要确认,请查看http://sqlfiddle.com/#!2/16831/5

    我不建议成为受虐狂,并尝试在单个查询中获得答案。

    我也不建议使用我提供的MySQL查询。它不那么自虐。但对我来说,充分的自虐不是推荐这种方式。

    由于你没有指出除mysql之外的任何标签,我怀疑你对mysql更强。因此我的答案包含mysql。

    我最强烈的建议是我的第一个。充分利用已建立的框架,并将您的逻辑放在业务逻辑层中。不在数据层中。即使你不使用框架并只使用原始的php和ruby,这仍然是一个比MySQL更好的放置逻辑的地方。

    我看到T在一个MySQL查询中给出了答案,但我可以告诉你,他只考虑了一个参数。

    见这部分:

    WHERE ParameterId = 7  -- 7 is the selected parameter
    

    你可以使用forloop和附加OR条款来调整他/她的答案。

    同样,我不建议在构建应用程序的大图中。

    我还用http://sqlfiddle.com/#!2/2eda4/2测试了他/她的回答。可能有1或2个小错误。

    总之,我的建议按强度降序排列:

    1. 根据需要使用Rails或CakePHP等框架和伪代码第1步和第2步以及find。 (最强)
    2. 使用原始脚本语言和伪代码第1步和第2步以及您需要的任意数量的简单查询。
    3. 使用我创建的原始MySQL查询。 (至少强)
    4. <强> P.S。我在查询中省略了如何获取参数名称的部分。但鉴于您可以从我的答案中获取ParameterID,我认为这是微不足道的。我也忽略了你可能需要删除已经选择的参数(1,7)。同样,这对你来说应该是微不足道的。