2017-07-17 271 views
1

我有表的集合在關係數據庫SQL - 計數與嵌套子查詢

  • products
  • categories
  • orders
  • line_items
  • customers

產品與類別具有多對多關係(連接表categories_products),並且也具有並屬於許多ordersline_items,這是productsorders的連接表,帶有一個id。 A 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進行計數。

如何才能讓計數正確地代表customercategory內購買的line_items的數量?

注意:在SQL文本中,o.status = 3正在使用枚舉來指示訂單是「完整的」。

+0

你的查詢看起來像它特定於類別。將刪除'number_purchased'返回一個類似的輸出? –

+0

我建議通過添加分組 –

+0

@RudyM'number_purchased'是唯一返回不正確的值。理論上我可以在每個'customer'和'category'的每個組合或代碼級別的單獨查詢中獲得'number_purchased'值,但是我特別試圖編寫單個SQL語句來正確輸出所有這些信息 – PapaPoison

回答

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 
+1

好的,這個評論讓我大部分時間都在那裏。一個額外的細節,幫助它完全正確的是,在我使用'customer_id'的子查詢中。用原來的'customers.id'代替,確保將正確的值傳遞給子查詢。 – PapaPoison

0

如果你想糾正你的計數,我會建議在子查詢中使用GROUP BY子句。如果您使用GROUP BY命令,那麼只有在查看用戶標識正確時才能獲取您檢索的特定訂單。我鼓勵你看看你的SQL代碼的其他部分的錯誤來清理這個龐大的查詢。例如,確保你想要使用不同的,並且你實際上想要使用左連接和內連接,這兩者都可能嚴重影響程序的性能。

+0

當你說GROUP BY命令時,你是什麼意思? 我向子查詢添加了一個GROUP BY語句('GROUP BY o。id'),這會使_first_計數正確,但每個後續行都錯誤地使用相同的計數。 例如,'customer1'的訂單中有3個'line_items' /'products','category'爲'Electronics'。對於第一行,「number_purchased」列計爲3 - 正確。然而,'customer2'有一個包含2個'line_items' /'products'的訂單,並且'category'爲'Books'。當伯爵應該是2時,伯爵仍然回到3點。那裏有什麼見解? – PapaPoison