按类型分组时使用哪个SQL范例?

问题描述

假设我有一个数据库,其中有一个比萨店的数据。我通过两个表customerorders来跟踪客户及其订单。 orders具有customer的FK,因此我可以轻松查看哪些订单属于哪个客户。

我可以像这样计算所有客户的订单:

SELECT
    c.id,COUNT(o.id) AS order_counts
FROM
    customers AS c,JOIN orders ON c.id = o.customer_id
GROUP BY
    c.id

这给了我这样的东西:

results = [
{
  “customer_number”: 1,“order_counts”: 5
},{
  “customer_number”: 2,“order_counts”: 10
}]

但是,如果我想“分解” order_counts结果以显示所有披萨类型,然后计算这些类型怎么办?我将添加一个名为pizzas的新表,该表具有一个name列,然后使结果看起来像这样:

results = [
{
  “customer_number”: 1,“counts”: {
    “Hawaiian”: 2,“Meat lovers”: 2,"Four Cheese": 1
  }
},“counts”: {
    “Hawaiian”: 5,“Meat lovers”: 5,"Four Cheese": 0
  }
}]

我需要利用哪些sql主体/范例来实现这一目标?我怀疑我需要子查询和/或嵌套的GROUP BY语句。

奖金问题:这在Django ORM中是可能的,还是很快达到ORM局限性的东西?

解决方法

结果可能包含多个客户ID,但数字是披萨特有的。

SELECT
    c.id,COUNT(o.id) AS order_counts,p.name
FROM
    customers AS c,JOIN orders o ON c.id = o.customer_id
    JOIN pizzas p ON p.id = o.pizzas_id
GROUP BY
    c.id,p.name
,

如果您确实想要这种嵌套输出,那么最好直接从数据库中生成JSON:

select
    c.id customer_id,sum(no_pizzas) no_orders,jsonb_object_agg(p.name,o.cnt_pizza) counts
from customers AS c,inner join (
    select customer_id,pizza_id,count(*) cnt_pizza
    from orders o 
    group by customer_id,pizza_id 
) o on c.id = o.customer_id
inner join pizza p  on p.id = o.pizza_id
group by c.id

这将产生列counts作为json对象,并以披萨名称为键,而披萨计数为值。另外,您仍然可以在no_orders列中获得订单总数。

如果您想吸引没有订单的客户,请使用left join s:

select
    c.id customer_id,coalesce(sum(no_pizzas),0) no_orders,left join (
    select customer_id,pizza_id 
) o on c.id = o.customer_id
left join pizza p  on p.id = o.pizza_id
group by c.id