我有桌子:
meal_categories
---------------------------
category_id | category_name
1 | Hot Drinks
2 | Cold Drinks
3 | Alcohol Drinks
meals
---------------------------------
meal_id | category_id | meal_name
1 | 1 | Tea
2 | 2 | Sprite
3 | 3 | Vodka + Sprite
meals_to_meals
------------------------
meal_id | mapped_meal_id
3 | 2
如您所见,任何一餐都可以包含任意数量的其他餐(来自相同/其他类别)。
假设我需要显示第3餐的类别(伏特加+雪碧)和所有子类别(以及其中的已用餐数)。因此结果应为:
category_name | total_meals
Alcohol Drinks | 1
Cold Drinks | 1
如果有人对这些数字的含义感到困惑:第三餐属于“酒精饮料”类别,那么我们就有1。第三餐也属于“冷饮”类别的一餐,所以我希望计算有意义。
对我来说最大的挑战是选择餐的子餐作为单独的行。如果我使用JOIN查询,它将仅返回一行(即使它正确返回了映射的饭食ID):
SELECT * FROM meals
JOIN meals_to_meals
ON meals.meal_id=meals_to_meals.meal_id AND meals.meal_id=3
因此,经过大量搜索,我决定使用UNION:
SELECT aaa.* FROM meals as aaa
JOIN meals_to_meals
ON aaa.meal_id=meals_to_meals.meal_id
GROUP BY aaa.meal_id
UNION ALL
SELECT meals.* FROM meals_to_meals
JOIN meals
ON meals_to_meals.mapped_meal_id=meals.meal_id
这个返回正确的进餐+映射的进餐(作为单独的行),但是如果我添加其他查询以显示进餐的类别和进餐数量,则会出现错误。使用的SELECT语句具有不同的列数
如果我能够在不使用UNION的情况下达到相同的结果,那么我敢肯定我可以设法显示类别(因此查询对我来说更容易理解)。有任何想法吗?
顺便说一下,这是小提琴,请随意使用-http://sqlfiddle.com/#!9/ 64313b/8
UNION ALL
只要是两个级别,它已经是最好的方法(一种饮料可以包含其他饮料,但是一种饮料不能包含本身包含其他饮料的其他饮料-为此,您需要一个递归查询,而MySQL不会这样做't功能)。
这是膳食3的查询:
select mc.category_name, count(*) as total_meals
from
(
select category_id from meals where meal_id = 3
union all
select category_id from meals where meal_id in
(select mapped_meal_id from meals_to_meals where meal_id = 3)
) c
join meal_categories mc using (category_id)
group by mc.category_name
order by mc.category_name;
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句