我正在使用Oracle Database 11g。 假设我有3个数据库表。一个包含有关披萨店的信息,一个包含有关人员的信息,另一个包含有关订单的信息:
PIZZA_SHOP
ID |名称|
1 | 多米诺
2 | 必胜客
3 | Papa Johns
PERSON
名称| PIZZA_SHOP_FK
吉姆 | 多米诺
托德 | 必胜客
凯利 | 多米诺
谢 | Papa Johns
订单的
PERSON_FK | ORDER
吉姆 | 辣
托德 | 干酪
凯利 | 辣
吉姆 | 香肠
托德 | 特
我们想省略特色披萨。从这张桌子上我们可以看到2个意大利辣香肠和1个香肠比萨饼是从多米诺(Dominos)订购的,1个奶酪比萨饼是从必胜客(Pizza Hut)订购的,没有从Papa Johns订购的。我想要做的是得到以下输出:
Dominos --- pepperoni --- 2
多米诺骨牌---香肠--- 1
多米诺斯---奶酪--- 0
必胜客---意大利辣香肠--- 0
必胜客---香肠--- 0
必胜客---奶酪--- 1
Papa Johns ---意大利辣香肠--- 0
爸爸约翰斯---香肠--- 0
爸爸约翰斯---奶酪--- 0
我尝试的是这样的:
选择PS.NAME,O.ORDER,COUNT(O.ORDER)
来自PIZZA_SHOP PS
全外联合人员P
ON P.PIZZA_SHOP_FK = PS.NAME
全外联合订单O
ON O.PERSON_FK = P.NAME
O.ORDER IN('Pepperoni','Cheese','Sausage')
GROUP_BY PS.NAME,PS.TYPE
但不幸的是,它没有检索到任何'0'计数。我已经尝试了其他几种方法,并且开始没有想法了。任何人都可以帮我解决问题吗?
答案 0 :(得分:4)
此类查询背后的想法是使用cross join
创建所有行,然后使用left join
和group by
将所需的数据组合在一起。这有点复杂,因为你在人和订单之间有这些奇怪的关系,但它仍然可行:
select ps.name, toppings.order, count(o.order)
from pizza_shop ps cross join
(select 'Pepperoni' as order from dual union all
select 'Cheese' from dual union all
select 'Sausage' from dual
) toppings left join
order o
on o.order = toppings.order left join
persons p
on p.pizza_shop_fk = ps.name and
p.name = o.person_fk
group by ps.name, toppings.order;