更快的 CROSS JOIN 替代方案 - PostgreSQL

发布于 2024-08-18 02:16:02 字数 615 浏览 5 评论 0原文

我正在尝试交叉联接两个表(客户和项目),这样我就可以创建按客户按项目的销售报告。我有 2000 个客户和 2000 个商品。

从客户中选择客户名称; --需要 100 毫秒

从项目中选择 item_number; --需要 50 毫秒

从客户中选择 customer_name、item_number CROSS JOIN 项目;需要 200000ms

我知道这是 400 万行,但是有可能让它运行得更快吗?我想最终将其与这样的销售表连接起来:

SELECT customer_name, item_number, sales_total FROMcustomers CROSS JOIN items LEFT JOIN sales ON (customer.customer_name = sales.customer_name, item.item_number=sales.item_number);< /code>

销售表显然不会包含所有客户或所有商品,因此这里的目标是有一个报告,显示所有客户和所有商品以及已售出和未售出的商品。

我正在使用 PostgreSQL 8.4

I am trying to CROSS JOIN two tables, customers and items, so I can then create a sales by customer by item report. I have 2000 customer and 2000 items.

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

I know this is 4 million rows, but is it possible to get this to run any faster? I want to eventually join this with a sales table like this:

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);

The sales table will obviously not have all customers or all items, so the goal here is to have a report that shows all customers and all items along with what was sold and not sold.

I'm using PostgreSQL 8.4

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

素衣风尘叹 2024-08-25 02:16:02

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

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

To answer your question: No, you can't do a cross join faster than that - if you could then that would be how CROSS JOIN would be implemented.

But really you don't want a cross join. You probably want two separate queries, one which lists all customers, and another which lists all items and whether or not they were sold.

喜爱纠缠 2024-08-25 02:16:02

这确实需要多份报告。我能立即想到几个可以产生更有效的信息包装的方法:

  1. 报告:按客户/商品统计所有购买的数量(显而易见)。
  2. 报告:客户未购买的所有商品的列表。
  3. 报告:报告 #2 的摘要(项目计数),以便确定要重点关注的客户的优先级。
  4. 报告:列出所有未购买商品的顾客的列表。
  5. 报告:报告#3(客户数量)摘要,以确定最受欢迎和不受欢迎的商品以采取进一步行动。
  6. 报告:过去购买过商品但在报告期间未购买的所有客户的列表。仅当销售表有日期并且客户预计是常规买家(即一次性小部件)时,此报告才相关。对于服务合同之类的事情不太适用。

这里的要点是,人们不应该坚持要求该工具立即处理所有可能的结果并生成更多数据,任何人都可以手动消化。人们应该让数据的最终用户和消费者了解他们的需求,并定制输出以满足这些需求。从长远来看,这将使双方的生活变得更加轻松。

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.

鼻尖触碰 2024-08-25 02:16:02

如果您希望查看给定客户的所有商品(即使该客户没有商品),我宁愿尝试

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

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

If you wish to see all items for a given client (even if the cient has no items), i would rather try

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

This should give you a list of all clients, and all items joined by sales.

红颜悴 2024-08-25 02:16:02

也许你想要这样的东西?

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

Perhaps you want something like this?

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文