1

我正在尝试 CROSS JOIN 两个表,客户和项目,因此我可以按客户逐项创建销售报告。我有 2000 个客户和 2000 个项目。

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

4

5 回答 5

5

回答您的问题:不,您不能比这更快地进行交叉连接 - 如果可以,那么这将是 CROSS JOIN 的实施方式。

但实际上你不想要交叉连接。您可能需要两个单独的查询,一个列出所有客户,另一个列出所有项目以及它们是否已售出。

于 2010-01-14T19:56:36.157 回答
1

This really needs to be multiple reports. I can think of several off the top of my head that will yield more efficient packaging of information:

  1. Report: count of all purchases by customer/item (obvious).
  2. Report: list of all items not purchased, by customer.
  3. Report: Summary of Report #2 (count of items) in order to prioritize which customers to focus on.
  4. Report: list of all customer that have not bought an item by item.
  5. Report: Summary of Report #3 (count of customers) in order to identify both the most popular and unpopular items for further action.
  6. Report: List of all customers who purchased an item in the past, but did not purchase it his reporting period. This report is only relevant when the sales table has a date and the customers are expected to be regular buyers (i.e. disposable widgets). Won't work as well for things like service contracts.

The point here is that one should not insist that the tool process every possible outcome at once and generate more data and anyone could possibly digest manually. One should engage the end-users and consumers of the data as to what their needs are and tailor the output to meet those needs. It will make both sides' lives much easier in the long run.

于 2010-01-19T18:25:36.810 回答
0

我无法想象会有第三方解决方案,PostgreSQL 程序员最了解他们的系统并将对其进行大量优化。

于 2010-01-14T19:57:39.543 回答
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

这应该为您提供所有客户的列表,以及销售加入的所有项目。

于 2010-01-14T19:59:24.090 回答
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
于 2014-02-16T20:21:31.853 回答