我是初学者程序员。我的MySQL查询有小问题。 这是我的MySQL数据:https://pastebin.com/69PcBSVH
我有这张桌子:
CREATE TABLE `dishes` (
`id` bigint(20) UNSIGNED NOT NULL,
`company_id` bigint(20) UNSIGNED NOT NULL,
`name` varchar(100) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`description` longtext COLLATE utf8mb4_unicode_ci,
`enable` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '1',
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `dish_values` (
`id` bigint(20) UNSIGNED NOT NULL,
`dishes_id` bigint(20) UNSIGNED NOT NULL,
`food_ingredient_id` bigint(20) UNSIGNED NOT NULL,
`company_id` bigint(20) UNSIGNED NOT NULL,
`quantity` decimal(9,2) NOT NULL DEFAULT '0.00'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `food_ingredients` (
`id` bigint(20) UNSIGNED NOT NULL,
`company_id` bigint(20) UNSIGNED NOT NULL,
`name` varchar(120) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`garbage` decimal(9,2) NOT NULL DEFAULT '0.00',
`energy_value` decimal(9,2) NOT NULL DEFAULT '0.00',
`protein` decimal(9,2) NOT NULL DEFAULT '0.00',
`fat` decimal(9,2) NOT NULL DEFAULT '0.00',
`available_carbohydrates` decimal(9,2) NOT NULL DEFAULT '0.00',
`roughage` decimal(9,2) NOT NULL DEFAULT '0.00',
`description` longtext COLLATE utf8mb4_unicode_ci,
`url_address` varchar(160) COLLATE utf8mb4_unicode_ci NOT NULL,
`allergen` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0',
`allergen1` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0',
`allergen2` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0',
`allergen3` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0',
`available_in_demo` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '0',
`enable` char(1) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '1'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
我的基地是准备菜肴所需的菜肴和食材的基地。
我需要显示所有不是过敏原的菜肴(food_ingredients.allergen = 0)。
Table dishes = given dishes
Table dish_values = ingredients that are assigned to a given dish
Food_ingredients table = ingredients of the dish.
过敏原的菜品在过敏原栏中的值为1,非过敏原的菜谱为0。
我查询以显示我的菜(没有过敏原):
SELECT
dishes.id, dishes.company_id, dishes.name, dishes.description, dishes.enable
FROM `dishes` join dish_values on dish_values.dishes_id = dishes.id
join food_ingredients on food_ingredients.id = dish_values.food_ingredient_id
WHERE food_ingredients.allergen = 0
GROUP BY dishes.id
但是它不能正常工作。
结果,我既有含有过敏原的菜肴,也有不含过敏原的菜肴。
我该如何修理?
答案 0 :(得分:0)
由于过敏原是char列,因此需要在0前后加上引号。或者,您可以将列更改为int。
答案 1 :(得分:0)
删除WHERE
子句,并将条件添加到HAVING
子句:
SELECT d.id, d.company_id, d.name, d.description, d.enable
FROM dishes d
INNER JOIN dish_values v ON v.dishes_id = d.id
INNER JOIN food_ingredients i ON i.id = v.food_ingredient_id
GROUP BY d.id, d.company_id, d.name, d.description, d.enable
HAVING SUM(i.allergen) = 0
条件SUM(i.allergen) = 0
确保表food_ingredients
中所有匹配的行都具有i.allergen = 0
。
答案 2 :(得分:0)
我将not’exists
与相关子查询一起使用:避免了聚合的需求,这通常不利于大型数据集的性能:
select d.*
from dishes d
where not exists (
select 1
from dish_values v
inner join food_ingredients i on i.id = v.food_ingredient_id
where
v.dishes_id = d.id
and i.allergen = 1
)
为了提高性能,您需要以下索引:food_ingredients(allergen, id)
。
旁注:由于allergen
的数据类型仅包含0/1值,因此应将其从char(1)
更改为tinyint(1)
。