MySQL或PHP:根据分数查找最佳行组合

时间:2014-09-21 10:40:31

标签: php mysql sql

我有一个包含以下列的MySQL数据库

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

我希望能够从表格中选择N行,这些行组合总得分最高,但受每种风味所能出现的次数限制。

例如,我可能想要选择5种最佳风味组合(行),没有单一风味出现超过3次(Flavour1 + Flavour2< 3的数量)

由于db必须比较所有组合以获得分数这一事实,我努力想要了解如何做到这一点,同时保持风味特征的次数。

任何帮助都非常感谢!!

编辑 - 如果有一种在PHP中执行此操作的算法方法,也是可以接受的。

1 个答案:

答案 0 :(得分: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

从算法上讲,可能有更有效的方法来解决这个问题。我怀疑贪婪的算法会更快,并会产生你想要的结果。