2010-01-14 93 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