SQL - 使用嵌套子查询进行计数

时间:2017-07-17 17:48:41

标签: mysql sql join subquery associations

我在关系数据库中有一组表

  • products
  • categories
  • orders
  • line_items
  • customers

产品与类别(加入表格categories_products)具有多对多关系,并且还拥有并属于许多ordersline_items,这是{products的连接表1}}和orders带有ID。 customer也有很多orders

我正在尝试整理一些能给我这种反应的SQL:

    customer_id | customer_first_name | category_id | category_name | number_purchased
    -----------------------------------
    1 |Jack | 1 | Electronics | 15
    2 |Jill | 1 | Electronics | 2
    2 |Jill | 2 | Hiking | 3

这是我一直试图用来获取这些值的巨大SQL:

    SELECT 
            DISTINCT customers.id AS customer_id,
            customers.first_name AS customer_first_name,
            categories.id AS category_id,
            categories.name AS category_name,
            (
                SELECT count(li.id) FROM line_items li
                INNER JOIN orders o ON li.order_id = o.id
                INNER JOIN products p ON li.product_id = p.id
                INNER JOIN categories_products cp ON cp.product_id = p.id
                WHERE
                    o.customer_id = customer_id 
                    AND o.status = 3
                    AND cp.category_id = category_id
            ) AS number_purchased
        FROM orders
        LEFT JOIN customers ON orders.customer_id = customers.id
        LEFT JOIN line_items li ON li.order_id = orders.id
        LEFT JOIN products ON products.id = li.product_id
        LEFT JOIN categories_products catpr ON catpr.product_id = products.id
        LEFT JOIN categories ON catpr.category_id = categories.id

只有计数本身是错误的。我没有获得客户在特定类别中购买的订单项数量,而是计算了已完成订单中所有LineItem的计数。

如何让计数正确表示line_items内特定customer购买的category的数量?

注意:在SQL文本中,o.status = 3使用枚举来表示订单是“完整的”。

2 个答案:

答案 0 :(得分:0)

如果你想更正你的计数,我会建议在子查询中使用GROUP BY子句。如果您是GROUP BY订单,那么您只会获得在查看用户ID正确时检索到的特定订单。我建议你看一下SQL代码其他部分的错误,以清理这个笨重的查询。例如,确保您希望使用distinct,并且您确实希望使用左连接与内连接,这两者都可能严重影响程序的性能。

答案 1 :(得分:0)

我认为你与categories_products的内心联系搞砸了。你应该像@Strawberry建议的那样设置一个小提琴,或试试这个:

SELECT 
        DISTINCT customers.id AS customer_id,
        customers.first_name AS customer_first_name,
        categories.id AS category_id,
        categories.name AS category_name,
        (
            SELECT count(li.id) FROM line_items li
            INNER JOIN orders o ON li.order_id = o.id
            INNER JOIN products p ON li.product_id = p.id
            WHERE
                o.customer_id = customer_id 
                AND o.status = 3
        ) AS number_purchased
    FROM orders
    LEFT JOIN customers ON orders.customer_id = customers.id
    LEFT JOIN line_items li ON li.order_id = orders.id
    LEFT JOIN products ON products.id = li.product_id
    LEFT JOIN categories_products catpr ON catpr.product_id = products.id
    LEFT JOIN categories ON catpr.category_id = categories.id