簡體   English   中英

如何在MySQL中請求包含某些項目的列表

[英]How to request lists that contain certain items in 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

現在,只有某些參數組合可供用戶使用。 在我的示例中,他可以得到一個紅色的圓木東西或一個綠色的圓木東西,但不能得到藍色的東西,因為我無法生產它。

假設用戶選擇了wood和round參數。 我如何請求知道只有紅色和綠色可用,所以我可以為他禁用藍色選項? 還是有一些更好的方法來對數據庫建模?

嘗試以下

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)

讓我們假設您以以下格式提供選定的參數id

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

我還假設您正在使用某種腳本語言來幫助您使用應用程序。 像紅寶石或PHP。

我還假設您想避免在存儲過程或MySQL查詢中盡可能多地添加邏輯。

另一個假設是您使用的是Rapid Application MVC框架之一,例如Rails,Symfony或CakePHP。

您的邏輯將是:

  1. 在您的parameterList找到包含所有參數的所有組合,並將找到的這些組合放在一個名為relevantCombinations的列表中
  2. 找到所有包含該組合中的至少1在列表中parameters_combinations relevantCombinations 僅檢索唯一的參數值。

可以使用簡單的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

請注意,我是如何故意組合3的,其中只有參數1而沒有參數7。因此查詢並沒有給您3,而只有1和2。請隨意在第一行中調整星號*。

第二個是

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查詢中給出了答案,但我可以告訴你,他只考慮1個參數。

看到這一部分:

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查詢。 (最少)

PS我在查詢中省略了有關如何獲取參數名稱的部分。 但是鑒於您可以從我的答案中獲取ParameterID,因此我認為這很簡單。 我也省略了您可能需要如何刪除已經選擇的參數(1、7)。 同樣,這對您來說應該是微不足道的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM