我正在尝试获取未订购6个月或更长时间的客户列表。我在查询中使用了4个表
客户和订单表分别很大,3M和26M行,因此在我的查询中使用左连接会使查询时间过长。我相信我已正确索引我的表
这是我用过的查询
SELECT cus.customer_id, MAX(o.order_date), cus.store_id, s.account_id, store_name
FROM customers cus
LEFT JOIN stores s ON s.store_id=cus.store_id
LEFT JOIN orders o ON o.customer_id=cus.customer_id AND o.store_id=cus.store_id
WHERE account_id=26 AND
(SELECT order_id
FROM orders o
WHERE o.customer_id=cus.customer_id
AND o.store_id=cus.store_id
AND o.order_date < CURRENT_DATE() - INTERVAL 6 MONTH
ORDER BY order_id DESC LIMIT 0,1) IS NOT NULL
GROUP BY cus.customer_id, cus.client_id;
我需要获取最后一个订单日期,这就是我加入订单表的原因,但是因为客户可以有多个订单,所以它返回了多行客户,这是为什么我使用了group by子句。
如果有人可以帮助我查询。
答案 0 :(得分:2)
从这开始:
SELECT customer_id, MAX(order_date) AS last_order_date
FROM orders
GROUP BY customer_id
HAVING last_order_date < NOW() - INTERVAL 6 MONTH;
假设为您提供了相关的customer_id,请转到
SELECT ...
FROM ( that-select-as-a-subquery ) AS old
JOIN other-tables-as-needed ON USING(customer_id)
如有必要,JOIN
返回订单以获取更多信息。 不尝试获取该子查询中的其他列。 (那是&#34; groupwise max&#34;问题。)
答案 1 :(得分:0)
您在orders
表上使用有序且有限的子查询的策略可能是您表现不佳的原因。
此子查询将生成一个虚拟表,显示每个不同客户的最新订单的日期。 (我猜一个独特的客户是由customer_id, store_id
对区分的。
SELECT MAX(order_date) recent_order_date,
customer_id, store_id
FROM orders
GROUP BY customer_id, store_id
然后,您可以在查询中使用该子查询,就好像它是一个表。
SELECT cus.customer_id, summary.recent_order_date,
cus.store_id, s.account_id, store_name
FROM customers cus
JOIN stores s ON s.store_id=cus.store_id
JOIN (
SELECT MAX(order_date) recent_order_date,
customer_id, store_id
FROM orders
GROUP BY customer_id, store_id
) summary ON summary.customer_id = cus.customer_id
AND summary.store_id = s.store_id
WHERE summary.recent_order_date < CURRENT_DATE - INTERVAL 6 MONTH
AND store.account_id = 26
此方法将GROUP BY
移动到内部查询,并消除了浪费的ORDER BY ... LIMIT
查询模式。不必为外部查询中的每一行重新创建内部查询。
我不明白您在查询中使用LEFT JOIN
操作的原因。
顺便说一句,大多数人,当他们不熟悉SQL时,对于哪些索引有用而哪些索引不是很有直觉。因此,在寻求帮助时,显示索引总是好的。在此期间,请阅读: