2012-03-01 62 views
0

我真的希望有人能幫助我。我有許多產品屬性類型,用戶可以從中進行選擇以優化屏幕上返回的產品。我想要做的是,對於每種產品屬性類型,我想列出與所選類別或搜索詞相關的所有屬性,然後一旦他們做出選擇,我仍然想要顯示每個屬性與類別或搜索詞相關,但只顯示可點擊的鏈接(如果該特定屬性的產品數大於1),對於那些產品數爲零的鏈接,我想列出它們,但使它們不可點擊。我試圖實現的一個例子可以在ASOS網站上找到,在左側菜單中 http://www.asos.com/Women/Dresses/Cat/pgecategory.aspx?cid=8799#state=Rf961%3D3340%2C3341%40Rf-200%3D20&parentID=Rf-300&pge=0&pgeSize=20&sort=-1臨時表和左連接沒有按預期顯示結果

最初我嘗試只用連接來實現這一點,但我無法成功完成。因此,我決定爲每個屬性類型創建一個臨時表,其中包含與主查詢相關的所有屬性的列表,然後使用左連接創建精煉的查詢。這裏是我的代碼:

CREATE TEMPORARY TABLE temp_table 
    SELECT su_types.id, type AS item FROM su_types 
    INNER JOIN su_typerefs ON su_types.id=su_typerefs.id 
    INNER JOIN su_pref ON su_typerefs.mykey = su_pref.mykey 
WHERE wp_category_id =40 GROUP BY su_typerefs.id 

$sudb->query($query); 

if ($sudb->affected_rows > 0) {  

SELECT temp_table.id,item,COUNT(su_typerefs.mykey) AS product_count FROM temp_table 
    LEFT JOIN su_typerefs ON temp_table.id=su_typerefs.id 
    LEFT JOIN su_pref ON su_typerefs.mykey = su_pref.mykey 
    LEFT JOIN su_stylerefs ON su_pref.mykey = su_stylerefs.mykey 
    LEFT JOIN su_productrefs ON su_pref.mykey = su_productrefs.mykey 
WHERE wp_category_id =40 AND su_stylerefs.id in (91) AND su_productrefs.id in (54) AND su_typerefs.id in (159) GROUP BY su_typerefs.id 

if ($itemresults = $sudb->query($query)) { 

    while($itemresult = $itemresults->fetch_array(MYSQLI_ASSOC)) { 
    $id=$itemresult['id']; 
    $item=$itemresult['item']; 
    $product_count=$itemresult['product_count']; 


     build_link($list_type, $item, $product_count, $id); 
    } 
} 

在上面的例子中,第一查詢選擇涉及特定類別的所有產品類型,說衣服。第二個查詢基於用戶對該類別的改進,在本例中,這是產品,產品類型和樣式。用戶還可以通過顏色,適合度,面料和設計來細化他們的搜索。

有幾個問題與此:

1)結果的數量在第二個查詢返回不匹配的第一個結果。以上述爲例,我希望列出與所選類別相關的所有產品,然後使用第二個查詢返回上述每種產品的產品數量。所以,如果臨時桌返回,褲子,牛仔褲和裙子。我期望這三個項目根據第二個查詢中應用的條件顯示在屏幕上,但是如果在第二個查詢中沒有裙子匹配,我的結果可能只會顯示褲子和牛仔褲。我認爲使用左連接意味着將顯示臨時表的所有結果。

2)此外,我不知道如果我這樣做是最有效的方式。我總共有8個屬性組,因此需要做上述8次。如果用戶選擇使用全部8個屬性組來優化結果,那麼除了臨時表連接之外,每種類型總共會有9個連接。執行需要一段時間,是否有更好的方法來執行此操作?表格中大約有一千五百萬個產品,一旦我的網站上線,這可能會是這個的五倍。

我真的希望我寫的都有道理,我會很感激的計算器社會這方面的幫助,如果任何人都可以提供幫助。我爲這篇短文道歉;)。在此先感謝

回答

0

要回答你的第一個問題;是的,LEFT JOIN確實會保留初始表中的所有數據。但是,這不是問題。

爲什麼你失去了空的類別,是最有可能的原因(我這樣說是因爲我不完全知道你的數據庫結構),因爲那裏的條件篩選出基於連接表數據中的所有結果。 如果對於某個類別,所有項目都被濾除(可能包括NULL連接的值),則不會再從該查詢中取回該類別。此外,GROUP BY是在連接的列上完成的,也可能會有效地清除其他類別。

至於第二個問題,你已經說出它採取長;所以如果你希望事情能夠快速運行,這可能不會成爲現實;)(好吧,明顯的答案,低懸的水果等)。您可能想要做的是首先從可篩選類別中獲取一組鍵,然後使用該數據選擇項目。

這可以防止你也來加入你的整個產品表中臨時表(至少,這就是我認爲你正在做的),當然,這將需要很長的條目的給定數。從給定的屬性中選擇一個匹配的ID列表也可以讓你更好地使用你的索引(更多),而臨時表可能不會有。如果這是可能和可行的,主要取決於你的模式結構;但我希望它會導致你的方向你想要去:)

+0

嗨Yhn,感謝您的回覆,臨時表不會檢索表中的所有屬性,但只涉及到所選類別的那些。我之前構建了第二個查詢,作爲通過每個我想要計數的鍵的循環。這很好,但花費了相同的時間,如果不是更多。目前需要大約30秒才能加載整個頁面,這是不可接受的嗎? – Amara 2012-03-01 15:41:30

+0

30秒,只是一些計數統計並聽起來像它應該能夠更好地工作......你可以嘗試同時檢查查詢的時序(只是爲了確認這兩者實際上是造成問題)。之後,您可以嘗試使用EXPLAIN [query]的輸出來查看索引是否正確用於連接和位置。也許它可以在沒有臨時表的情況下工作得更快(因爲這可能沒有索引;而實際的表有)。 – Yhn 2012-03-01 15:49:36

+0

我試圖做一個關於臨時表查詢的解釋,但我無法做到。但是sedond查詢的解釋看起來很好。如果我不使用臨時表,然後我會創建通過第一循環,而不是加入第二查詢到臨時表和一個返回所有結果第二次查詢擊中 – Amara 2012-03-01 16:45:39