2013-08-21 77 views
0

在我開發的應用程序中,用戶必須設置參數以定義他將獲得的最終產品。如何請求包含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 

現在只有一些參數組合提供給用戶。在我的例子中,他可以得到一個紅色的圓形木製玩具或一個綠色的圓形木製玩具,但不是藍色的,因爲我無法制作它。

假設用戶選擇了木材和圓形參數。我如何提出請求,知道只有紅色和綠色可用,因此我可以禁用他的藍色選項? 或者有更好的方法來建模我的數據庫嗎?

+0

是的,EAV沒有太多的樂趣!但它的確有其用途。 – Strawberry

回答

0

讓我們假設你提供選擇的參數ID的格式如下

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

我也是假設您正在使用一些腳本語言來幫助您使用您的應用程序。像紅寶石或PHP。

我還假設你想避免儘可能多地將邏輯放入存儲過程或MySQL查詢中。

另一個假設是您正在使用Rails,Symfony或CakePHP等Rapid Application MVC框架之一。

你的邏輯是:

  1. 找到所有包含在你的parameterList所有的參數組合,並把這些發現的組合在一個叫relevantCombinations
  2. 列表中找到所有包含的至少1 parameters_combinations列表中的組合爲relevantCombinations。僅檢索唯一參數值。

前兩個步驟可以使用簡單的Model :: find方法和上述框架中的forloop來解決。

如果您不使用框架,使用腳本語言raw也很酷。

如果你在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和紅寶石,對於你來說,放置你的邏輯仍然比MySQL更好。

我看到T在單個MySQL查詢中給出了答案,但我可以告訴你他認爲只有1個參數。

請參見本部分:

WHERE ParameterId = 7 -- 7 is the selected parameter 

您可以調整他/她使用for循環和附加條款或弄虛作假的一些答案。

同樣,我不建議在構建應用程序的大圖中。

我也用http://sqlfiddle.com/#!2/2eda4/2測試了他/她的答案。可能有1個或2個小錯誤。

總之,我在力量的遞減順序建議:

  1. 使用像導軌或CakePHP的框架和僞步1和2以及多達find根據您的需要。 (STRONGEST)
  2. 使用原始腳本語言和僞代碼步驟1和2以及儘可能多的簡單查詢。
  3. 使用我創建的原始MySQL查詢。 (最小強度)

P.S.我在查詢中忽略瞭如何獲取參數名稱的部分。但鑑於您可以從我的答案中獲取ParameterID,我認爲這很簡單。我也遺漏了你可能需要刪除已經選擇的參數(1,7)。再一次,這對你來說應該是微不足道的。

+0

我剛開始使用過程式PHP,但我想要更清潔的東西,所以我重新考慮了它,並認爲我最好使用框架。現在我打算使用Yii,但這是我第一次使用框架,所以我不確定它將如何處理。感謝你的回答,我現在對自己的選擇更有信心。 – Loonie

+0

你也可以使用Yii。 –

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) 
相關問題