【问题标题】:SELECT row with largest number of intersects选择交叉点数最多的行
【发布时间】:2019-01-14 16:12:00
【问题描述】:

对于以下两个表

+-----------+-----------+
| recipe_id | some_data |
+-----------+-----------+
|         1 | etc       |
|         2 | etc       |
+-----------+-----------+


+----------------+-----------+
| ingredients_id | recipe_id |
+----------------+-----------+
|              1 |         1 |
|              1 |         2 |
|              2 |         1 |
|              2 |         3 |
+----------------+-----------+

根据一组成分,我想选择最匹配的食谱。
例如,如果我要查询“牛奶、鸡蛋、盐”,我会得到 recipe_id 1 作为第一个结果(因为它有 2 个匹配项)但是如果我要搜索“牛奶”,则检索 1 或 3 作为第一个答案会等价。
我目前的努力找不到“最佳”选项,而只能通过将每个配方的不同成分相交来“全有或全无”(ing_id_1_input 是用户的输入):

select r1.*
from (
select distinct ing1.recipe_id as recipe_id
from ingredients as ing1
where ing1.ing_id=ing_id_1_input) as prod_1 join
(select distinct ing2.recipe_id
from ingredients as ing2
where ing2.ing_id=ing_id_2_input) as prod_2
on prod_1.recipe_id=prod_2.recipe_id
join recipes as r1 on r1.recipe_id=prod_1.recipe_id

【问题讨论】:

  • DISTINCT 不是列上的函数,它适用于整个选定的行!!!跳过这些括号,只需执行select distinct ing1.recipe_id as recipe_id ... 即可编写更清晰的代码!
  • 您的示例数据让我感到困惑。为什么相同的增量有 2 个条目?既然我们知道成分将在多个食谱中使用,为什么成分和食谱之间存在一对一的关系?
  • 我删除了 ing_name,可能是混淆了,但关系不是一对一的

标签: mysql sql


【解决方案1】:

你会这样做:

select i.recipe_id
from ingredients i
where i.ingredient_name in ('milk', 'egg', 'salt')
group by i.recipe_id
order by count(*) desc;

【讨论】:

    【解决方案2】:

    也许这行得通:

    select r.*, (select count(*) 
                   from ingredients as i1 where i1.recipe_id = r.recipe_id)
            - (select count(*) 
                 from ingredients as i1 where ingredient_name in (input1,input2,input3) 
                                          and i1.recipe_id = r.recipe_id)
               as missing
     from recipe r
    order by missing 
    

    input1、input2、input3 是 3 种可用的成分。此列表可以有可变长度。

    最后一列包含缺失成分的数量,如果所有成分都可用,则为 0。因此,按此列排序会将最小值放在最前面。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-04-07
      • 2011-09-15
      • 1970-01-01
      • 2015-06-02
      • 1970-01-01
      • 2017-07-18
      • 2019-04-23
      相关资源
      最近更新 更多