2014-09-21 43 views
0

行的組合我有以下的列MySQL或PHP:尋找最佳的基於分數

Flavour1| Flavour2  | Score 
------------------------------------- 
Vanilla | Strawberry | 7 
Choc | Toffee  | 8 
Vanilla | Choc   | 6 
Toffee | Vanilla  | 7 

等等

我希望能夠從表中選擇N行MySQL數據庫,其,總計得分最高,但受到每種風味特徵次數的限制。

例如,我可能要選擇最好的5個味道組合(行)與出現3次以上(Flavour1 +計數Flavour2 < 3)無單味

我努力讓我的頭圍繞如何做到這一點,由於事實上數據庫必須比較所有組合來獲得分數,同時保持風味特徵的次數。

任何幫助非常感謝!

編輯 - 如果有一個算法的方式來做到這一點在PHP中也是可以接受的。

+2

這顯然是錯誤的。太妃糖|香草應該有最高的分數! :-)無論如何,考慮提供一個更合適的代表性數據集(最好是一組DDL和/或sqlfiddle)以及相應的結果集。 – Strawberry 2014-09-21 10:45:26

+0

味道的順序是重要的嗎?我的意思是如果你有太妃糖|香草| 7它是否也意味着香草|太妃糖| 7? – 2014-09-21 11:28:28

+0

訂單並不重要,但所有可能的組合都將在表格中以行的形式出現,並且分數可能在將來發生變化。 – user1491032 2014-09-21 16:17:50

回答

0

正如指定的那樣,在SQL中沒有「有效」的方法來做到這一點。您可以通過生成所有組合,然後在where子句中應用所需的規則來執行此操作。讓我還假設你在每一列上都有一個id,唯一標識一對。

在你的情況,因爲你允許重複,我想補充一個計數每個組合和使用,對於組合:

create view v_withcounts as 
    select t.*, 1 as cnt 
    from table t 
    union all 
    select t.*, 2 as cnt 
    from table t 
    union all 
    select t.*, 3 as cnt 
    from table t; 

那麼對於查詢:

select v1.id, coalesce(v1.cnt), 
     v2.id, coalesce(v2.cnt), 
     v3.id, coalesce(v3.cnt), 
     v4.id, coalesce(v4.cnt), 
     v5.id, coalesce(v5.cnt) 
from v_withcounts v1 left join 
    v_withcounts v2 
    on v2.id not in (v1.id) left join 
    v_withcounts v3 
    on v3.id not in (v1.id, v2.id) left join 
    v_withcounts v4 
    on v4.id not in (v1.id, v2.id, v3.id) left join 
    v_withcounts v2 
    on v5.id not in (v1.id, v2.id, v3.id, v4.id) 
where (coalesce(v1.cnt, 0) + coalesce(v2.cnt, 0) + coalesce(v3.cnt, 0) + 
     coalesce(v4.cnt, 0) + coalesce(v5.ccnt, 0) 
    ) = 5 

從算法,有可能是更有效的方法來解決這個問題。我懷疑一個貪婪算法會更快,並會產生你想要的結果。

+0

謝謝 - 我可以看到這是如何工作的,但它在我的MySQL服務器上超時了,所以我假設我應該用算法實現PHP。有什麼想法嗎? – user1491032 2014-09-21 16:16:35

+0

@ user1491032。 。 。首先,在一小部分數據上嘗試一下,看看邏輯是否有效。您在php中會遇到類似的問題,因爲您必須創建一個5路笛卡爾產品來解決您所描述的問題。 – 2014-09-21 16:20:41