如何在食谱成分表中获得每个食谱ID的独特成分数量。 MySQL的

时间:2018-01-10 17:57:04

标签: mysql sql

我正在运行查询,查找具有特定成分的食谱。这些成分与查询一起发送,例如"糖,牛奶,鸡蛋"。食谱(recipe_id' s)按照它们中发现的成分的数量排序,所以如果配方中含有糖,牛奶和鸡蛋,它会得到在只有2种成分的食谱之前订购。

查询

structs

配料表

SELECT
    recipe_id, COUNT(ingredient) AS ingredient_count
FROM
    ingredients
WHERE
    ingredient LIKE '%sugar%'
    OR ingredient LIKE '%milk%'
    OR ingredient LIKE '%egg%'
GROUP BY
    recipe_id
ORDER BY
    ingredient_count DESC;

由于所有数据都有疤痕,配料表的结构很糟糕。将这些成分与单位和量混合,例如" 2杯糖"。这就是我必须使用通配符来找到成分的原因。一种配方也可以多次含有一种成分,例如" 1杯糖"和" 2杯糖" (这是由于子食谱),这是我开始遇到问题的地方。因为我的where子句会找到2" sugar"在配方中,ingredient_count将增加2(ofc),但我只希望它增加1,因为只有一种成分,"糖"。

所以我想要完成的是以某种方式计算查询返回的所有成分但是如果多次找到一种成分,例如" 2杯糖"," 1杯糖"我只想把它算作1,因为他们都有"糖"在他们中间。

此查询按计数执行我想要的操作,但由于某种原因,只返回很少的食谱,它应该返回更多。

此查询不是由我做的

id | recipe_id | ingredient      |
---|-----------|-----------------|
1  | 1         | 2 cups of sugar |

...

3 个答案:

答案 0 :(得分:0)

SELECT *, 
       IF(ingredient LIKE '%sugar%', 1, 0) as sgr,
       IF(ingredient LIKE '%milk%', 1, 0) as mlk,
       IF(ingredient LIKE '%egg%', 1, 0) as gg
FROM
    ingredients
    WHERE
        (ingredient LIKE '%sugar%')
        OR (ingredient LIKE '%milk%')
        OR (ingredient LIKE '%egg%')
ORDER BY sgr + mlk + gg DESC;

答案 1 :(得分:0)

如果你可以将“unit”和“ingredient_name”分成2个单独的列,那么你可以用这个来完成它:

SELECT
    recipe_id, COUNT(DISTINCT ingredient_name) AS ingredient_count
FROM
    ingredients
WHERE
    ingredient_name LIKE '%sugar%'
    OR ingredient_name LIKE '%milk%'
    OR ingredient_name LIKE '%egg%'
GROUP BY
    recipe_id
ORDER BY
    ingredient_count DESC;

但是你要问的是,MySQL要知道用“1杯糖”之类的字符串,“1杯”和“糖”是2个独立的值,它可以操作

但是,如果您始终可以依赖“of”作为分隔符,那么您可以尝试使用某些动态计算 ingredient_name 巧妙地使用MySQL字符串搜索和斩波功能。性能非常差,这将用以下内容替换上述查询中的“ingredient_name”:

SUBSTR(ingredient,LOCATE(' of ', ingredient)+4)

答案 2 :(得分:0)

扩展@ ast-tm回答:

这个答案仍然没有多次解决"成分"重复计算。此外,原始问题需要按食谱分组的结果。

然而,我仍然不确定它在技术上给你的是独特成分的数量",只有糖或牛奶或鸡蛋成分的数量。例如。如果配方中含有10种其他成分(不是牛奶或糖或蛋),那么这些成分在计数中将被忽略。

一般来说,必须将所有可能的成分名称放入查询中的想法是糟糕的设计。并且查询变得非常混乱。但万一它有帮助:

SELECT *, 
       IF(ingredient LIKE '%sugar%', 1, 0) as sgr,
       IF(ingredient LIKE '%milk%', 1, 0) as mlk,
       IF(ingredient LIKE '%egg%', 1, 0) as gg
FROM
    ingredients
    WHERE
        (ingredient LIKE '%sugar%')
        OR (ingredient LIKE '%milk%')
        OR (ingredient LIKE '%egg%')
GROUP BY
    recipe_id
ORDER BY
    (MAX(sgr) + AMX(mlk) + MAX(gg)) DESC;

我还想考虑其他成分,你可以尝试将你的WHERE移动到HAVING子句,然后使用GROUP_CONCAT(对于除了"糖和#34之外的任何东西仍然没有解决重复计算问题;,"牛奶"或#34;鸡蛋")。

这可能有助于更接近您的需求:

SELECT *, 
       IF((ingredient NOT LIKE '%sugar%' AND ingredient NOT LIKE '%milk%' AND ingredient NOT LIKE '%egg%'), 1, 0) as others,
       IF(ingredient LIKE '%sugar%', 1, 0) as sgr,
       IF(ingredient LIKE '%milk%', 1, 0) as mlk,
       IF(ingredient LIKE '%egg%', 1, 0) as gg
FROM
    ingredients
GROUP BY
    recipe_id
HAVING
        (GROUP_CONCAT(ingredient) LIKE '%sugar%')
        OR (GROUP_CONCAT(ingredient) LIKE '%milk%')
        OR (GROUP_CONCAT(ingredient) LIKE '%egg%')
ORDER BY
    (others + MAX(sgr) + AMX(mlk) + MAX(gg)) DESC;