我有桌子:
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次餐( Vodka + Sprite )的类别以及任何子类别(以及其中的用餐次数)如果有饭的话。所以结果应该是:
category_name | total_meals
Alcohol Drinks | 1
Cold Drinks | 1
如果有人对这些数字意味着什么感到困惑:第3次餐是属于酒精饮料本身,所以我们有1和第3次餐还有1餐从Cold Drinks类别在里面,所以我希望计算有意义。
对我来说,最大的挑战是选择分餐作为单独的行。如果我使用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
答案 0 :(得分:1)
UNION ALL
已经是最好的方法了,只要这只是两个级别(饮料可以包含其他饮料,但饮料不能包含其他饮料本身由其他饮料组成 - 您为此而且# 39; d需要一个MySQL没有特色的递归查询。
以下是用餐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;