2010-01-14 96 views
0

我想要CROSS JOIN兩個表,客戶和物品,這樣我就可以通過物料創建銷售報表了。我有2000個客戶和2000個項目。更快的CROSS JOIN替代方案 - PostgreSQL

SELECT customer_name FROM customers; --Takes 100ms

SELECT item_number FROM items; --Takes 50ms

SELECT customer_name, item_number FROM customers CROSS JOIN items; Takes 200000ms

我知道這400萬行,但有可能得到這個跑得更快?我想與銷售表像這樣最終加入這個:

SELECT customer_name, item_number, sales_total FROM customers CROSS JOIN items LEFT JOIN sales ON (customer.customer_name = sales.customer_name, item.item_number=sales.item_number);

銷售表顯然不會有所有客戶或所有項目,所以這裏的目標是有一個報告,顯示所有客戶和所有物品以及已售出而未售出的物品。

我使用PostgreSQL 8.4

+2

你** **實際上希望顯示爲所有客戶/項的所有組合,即使他們沒有他們,我的意思是給定的CUTOMER可能只有1項,那麼你可能會顯示1999年不需要的項目? – 2010-01-14 19:53:38

+0

其實我是這麼做的,因爲我想看看顧客還沒有訂購什麼,所以我可以試着把它賣給他們。 – bendiy 2010-01-17 00:39:52

回答

4

要回答你的問題:不,你不能做一個交叉連接比快 - 如果你能那麼這將是CROSS JOIN如何將實施。

但是你真的不想交叉加入。您可能需要兩個單獨的查詢,一個列出所有客戶,另一個列出所有項目以及是否已售出。

+0

我將不得不在應用程序級別嘗試兩個查詢,並查看在循環遍歷所有客戶和項目組合時是否更快。但是,如果應用程序能夠比數據庫更快地完成操作,我會感到驚訝。 – bendiy 2010-01-17 00:57:00

0

我無法想象會有第三方解決方案,PostgreSQL程序員最瞭解他們的系統,並會大量優化它。

0

如果你想看到一個給定的客戶端(即使cient沒有項目)的所有項目,我寧願嘗試

SELECT c.customer_name, i.item_number, s.sales_total 
FROM customers c LEFT JOIN 
    sales s ON c.customer_name = s.customer_name LEFT OIN 
    items i on i.item_number=s.item_number 

這應該給你的所有客戶端的列表,並且所有項目加盟通過銷售。

+0

這隻給你每個顧客訂購的物品,而不是每個顧客訂購的所有物品。所以我不知道每個客戶還沒有購買什麼。 – bendiy 2010-01-17 00:51:55

1

這確實需要多個報告。按客戶/項目(明顯)所有購買的數量:我能想到的幾個把我的頭頂部,將產生的信息更有效的包裝:

  1. 報告。
  2. 報告:客戶未購買的所有物品清單。
  3. 報告:報告#2摘要(項目數量),以便優先考慮哪些客戶關注。
  4. 報告:所有未購買物品的客戶列表。
  5. 報告:報告#3摘要(客戶數量),以便確定最受歡迎和不受歡迎的項目,以便採取進一步行動。
  6. 報告:所有過去購買商品但未在報告期購買商品的客戶列表。該報告僅在銷售表具有日期並且客戶希望成爲常規買家(即,一次性小部件)時纔是相關的。對於諸如服務合同之類的東西,效果不佳。

的這裏的一點是,人們不應該堅持這個工具處理每一個可能的結果,同時,併產生更多的數據和任何人所能手動消化。人們應該讓數據的最終用戶和消費者瞭解他們的需求,並定製輸出以滿足這些需求。從長遠來看,這將使雙方的生活變得更加容易。

0

也許你想要這樣的東西?

select c.customer_name, i.item_number, count(s.customer_name) as total_sales 
from customers c full join sales s on s.customer_name = c.customer_name 
full join items i on i.item_number = s.item_number 
group by c.customer_name, i.item_number