【问题标题】:SQL -- Counting with nested subquerySQL -- 使用嵌套子查询计数
【发布时间】:2017-12-22 08:45:10
【问题描述】:

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

  • products
  • categories
  • orders
  • line_items
  • customers

Products 与类别具有多对多关系(连接表categories_products),并且还拥有并属于许多ordersline_items,这是productsorders 的连接表一个身份证。一个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

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

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

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

【问题讨论】:

  • 您的查询看起来像是特定于类别的。删除 number_purchased 会返回类似的输出吗?
  • 我建议添加 group by's
  • @RudyM number_purchased 是唯一返回错误的值。理论上,我可以在单独的查询中为customercategory 的每个组合或在代码级别获得number_purchased 值,但我特意尝试编写单个SQL 语句来正确输出所有这些信息跨度>
  • @PapaPoison ,所以对于 Jill,两行都得到 3?
  • @RudyM,不,我得到的是第一行,Jack 的所有行数为 15。

标签: mysql sql join subquery associations


【解决方案1】:

我认为你与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

【讨论】:

  • 好的,这条评论让我大获成功。一个额外的细节有助于让它一直正确,在子查询中我使用了customer_id。将其替换为原始的 customers.id 可确保将正确的值传递给子查询。
【解决方案2】:

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

【讨论】:

  • 您说的 GROUP BY 订单是什么意思?我在子查询 (GROUP BY o.id) 中添加了一个 GROUP BY 语句,这使得 first 计数正确,但随后的每一行错误地使用了相同的计数。例如,customer1 有一个带有 3 个 line_items/productscategory“电子”的订单。 number_purchased 列被计为 3——对于第一行是正确的。但是,customer2 的订单包含 2 个 line_items/productscategory“书籍”。当它应该是 2 时,计数仍然回到 3。那里有什么见解吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多