2011-12-01 34 views
0

基本模式(只显示相关字段):MySQL的 - 查询返回客户的第一顺序

客户

id | fname | sname | email 

订单

order_id | customer | level | timestamp 

,我需要选择每一个客户,但随着他们的个人资料,我想加入他们的level第一个订单。

SELECT c.fname, c.sname, c.email, o.level 
FROM customers c 
LEFT JOIN orders o ON c.id = o.customer 

..? 

编辑

到目前为止我尝试了两种解决方案,他们完全杀死我的整个数据库。运行查询后没有数据库请求会完成,所以我想知道如果查询可能太大。大约有10,000个订单和15,000个客户。这是预期的吗?在这些桌子上我从来没有遇到过这些问题。

回答

0

那么,这将工作,但不是最优的:

SELECT c.fname, c.sname, c.email, o.level 
FROM customers c 
LEFT JOIN orders o ON c.id = o.customer 
WHERE o.`timestamp` = (SELECT MIN(o1.`timestamp`) FROM orders o1 WHERE o1.customer = c.id) 
GROUP BY c.id 
0
SELECT c.fname, c.sname, c.email, o.level 
FROM customers c 
LEFT JOIN orders o ON c.id = o.customer 
ORDER BY o.timestamp ASC LIMIT 1 
+0

这似乎已经杀死了我的数据库,但我不知道为什么。该请求已运行近10分钟。 – BadHorsie

+0

'LIMIT 1'告诉你只会得到一个结果行。只意味着一个客户,而不是所有的客户都有一个订单。请参阅下面的查询。希望它可以帮助你。 – yas375

+0

是的,我已经看到,但不幸的是我跑上面的查询,订单和客户表似乎已经死亡。如果我尝试在这两个表的数据库上运行任何查询,它将永远加载并永远不会完成。我可以阻止它,如果我重新启动服务器来终止进程,但这些表上的任何请求将再次杀死所有内容。我需要紧急解决这个问题。 – BadHorsie

0

尝试此查询 -

SELECT c.fname, c.sname, c.email, o.level FROM customers c 
    LEFT JOIN (
    SELECT o1.* FROM orders o1 
     JOIN (SELECT customer, MIN(timestamp) timestamp FROM orders GROUP BY customer) o2 
     ON o1.customer = o2.customer AND o1.timestamp = o2.timestamp) o 
    ON c.id = o.customer; 
+0

此查询也杀死了我的数据库。 – BadHorsie

+0

首先尝试使用小数据集。你有order.customer,orders.timestamp,customers.id字段的索引吗?他们应该提高性能。 – Devart

0
SELECT c.fname, c.sname, c.email, o.level 
FROM customers c 
LEFT JOIN orders o ON c.id = o.customer 
ORDER BY o.timestamp 
GROUP BY c.id 
+0

此查询也杀死了我的数据库。 – BadHorsie

+0

检查表格的名称。 '订单'表中的字段'客户'是整数吗? – yas375

0

子选择肯定不是最有效的,但这里有一个查询

SELECT c.fname, c.sname, c.email, o.level, 
    (select level from orders 
    where c.id = o.customer order by timestamp asc limit 0,1) as level 
FROM customers c 

这会给你所有的客户(订单与否)和他们相应的水平。如果你的表现很慢,请确保你有适当的索引