我在这里遇到了一些难题。我正在烘焙食谱应用程序,让我说我有一个“蛋黄酱”,“培根”和“奶酪”的查询。
如果他们有“蛋黄酱”,“培根”和“奶酪”,后面跟那些只有“蛋黄酱”的人,我想要退回所有含有“蛋黄酱”或“培根”或“奶酪”的食谱。 “培根”等。
到目前为止,我有点像克洛伊一样的东西:
SELECT * FROM recipes
WHERE LOWER(ingredients) LIKE '%mayonnaise%'
OR LOWER(ingredients) LIKE '%bacon%'
但那只是我想要的一半。我如何跨越终点线?
谢谢!
答案 0 :(得分:1)
您可以尝试优先考虑成分的存在,并根据成分是否包括在内进行排序:
SELECT * FROM recipes
WHERE LOWER(ingredients) LIKE '%mayonnaise%'
OR LOWER(ingredients) LIKE '%bacon%'
OR LOWER(ingredients) LIKE '%cheese%'
ORDER BY LOWER(ingredients) LIKE '%mayonnaise%' DESC,
LOWER(ingredients) LIKE '%bacon%' DESC,
LOWER(ingredients) LIKE '%cheese%' DESC
答案 1 :(得分:0)
我不知道食谱是否有主键,但我认为它确实如此。让我们给每个单词1分。
SELECT r.* FROM recipes
LEFT JOIN recipes m ON r.id = m.id AND LOWER(m.ingredients) LIKE '%mayonnaise%'
LEFT JOIN recipes b ON r.id = b.id AND LOWER(b.ingredients) LIKE '%bacon%'
LEFT JOIN recipes c ON r.id = c.id AND LOWER(c.ingredients) LIKE '%cheese%'
ORDER BY
(CASE WHEN m.id IS NULL THEN 0 ELSE 1 END)+
(CASE WHEN b.id IS NULL THEN 0 ELSE 1 END)+
(CASE WHEN c.id IS NULL THEN 0 ELSE 1 END) DESC
答案 2 :(得分:0)
如果可能(并且您似乎正在构建新的东西),也许您应该重新考虑您的表格布局。看来你有一个列中的成分,可能是逗号分隔或其他东西。这真的不能很好地扩展,甚至可以使你想到的简单查询变得复杂和缓慢(在实际搜索术语之前使用所有这些通配符可以有效地禁用任何索引)。
可能建议使用单独的INGREDIENTS表,其中n:m基数与RECIPES表的关系。
在伪SQL中:
CREATE TABLE RECIPES (id int not null, [...more columns...]) PRIMARY KEY id;
CREATE TABLE INGREDIENTS (id int not null, name varchar(30), [...more columns...]) PRIMARY KEY id;
CREATE TABLE RECIPE_INGREDIENTS (recp_id int not null, ingred_id not null);
这样你可以加入RECIPES和INGREDIENTS:
SELECT RECIPES.id AS recipe, COUNT(INGREDIENTS.id) AS matching_ingredients
FROM RECIPES r JOIN RECIPE_INGREDIENTS ri ON r.ID=ri.recp_id
JOIN INGREDIENTS i ON ri.ingred_id = i.id
WHERE INGREDIENTS.name in ('mayonnaise', 'bacon', 'cheese')
GROUP BY COUNT(INGREDIENTS.id)
指向配方编号表和匹配成分的数量。这也可以从索引中受益。
请注意,我现在手头没有MySQL服务器,所以上面写的是我的头脑。也许我的语法错了一点。此外,您可能希望添加外键信息,但这并不是运行它所必需的。
请参阅MySQL手册中的CREATE TABLE
语法。